Belajar PHP OOP Part 1.20 : Trait (Properties, Function Overriding, Overriding, Visibility Override)
- Selain class dan interface, di PHP terdapat feature lain bernama trait
- Trait mirip dengan abstract class, kita bisa membuat konkrit function atau abstract function
- Yang membedakan adalah, di trait bisa kita tambahkan ke dalam class lebih dari satu
- Trait mirip seperti ekstension, dimana kita bisa menambahkan konkrti function ke dalam class dengan trait
- Secara sederhana trait adalah digunakan untuk menyimpan function-function yang bisa digunakan ulang di beberapa class
- Untuk menggunakan trait di class, kita bisa menggunakan kata kunci use
<?php
namespace Data\Traits;
trait SayGoodBye
{
public string $name;
public function goodBye (?string $name): void
{
if (is_null($name)) {
echo "Good bye" . PHP_EOL;
} else {
echo "Good Bye $name" . PHP_EOL;
}
}
}
trait SayHello
{
public string $name;
public function hello (?string $name): void
{
if (is_null($name)) {
echo "Hello" . PHP_EOL;
} else {
echo "Hello $name" . PHP_EOL;
}
}
}
class Person
{
use SayGoodBye, SayHello;
}
<?php
require_once "data/SayGoodBye.php";
use Data\Traits\{Person, SayHello, sayGoodBye};
$person = new Person();
$person->goodBye("Joko");
$person->hello("Budi");
Trait Properties
- Berbeda dengan interface, di trait, kita bisa menambahkan properties
- Dengan menambahkan properties, secara otomatis class tersebut akan memiliki properties yang ada di trait
<?php
namespace Data\Traits;
trait SayGoodBye
{
public string $name;
public function goodBye (?string $name): void
{
if (is_null($name)) {
echo "Good bye" . PHP_EOL;
} else {
echo "Good Bye $name" . PHP_EOL;
}
}
}
trait SayHello
{
public string $name;
public function hello (?string $name): void
{
if (is_null($name)) {
echo "Hello" . PHP_EOL;
} else {
echo "Hello $name" . PHP_EOL;
}
}
}
// Trait Menambahkan Properties
trait HashName
{
public string $name;
}
class Person
{
use SayGoodBye, SayHello, HashName;
}
<?php
require_once "data/SayGoodBye.php";
use Data\Traits\{Person, SayHello, sayGoodBye};
$person = new Person();
$person->goodBye("Joko");
$person->hello("Budi");
//Trait Menambahkan Properties
$person->name = "Eko";
var_dump($person);
Trait Function Overriding
- Selain konkrit function, di trait juga kita bisa menambahkan abstract function
- Jika terdapat abstract function di trait, maka secara otomatis function tersebut harus di override di class yang menggunakan trait tersebut
Sebelum function di overriding
<?php
namespace Data\Traits;
trait SayGoodBye
{
public string $name;
public function goodBye (?string $name): void
{
if (is_null($name)) {
echo "Good bye" . PHP_EOL;
} else {
echo "Good Bye $name" . PHP_EOL;
}
}
}
trait SayHello
{
public string $name;
public function hello (?string $name): void
{
if (is_null($name)) {
echo "Hello" . PHP_EOL;
} else {
echo "Hello $name" . PHP_EOL;
}
}
}
trait HashName
{
public string $name;
}
trait CanRun
{
public abstract function run(): void;
}
class Person
{
use SayGoodBye, SayHello, HashName, CanRun;
}
<?php
require_once "data/SayGoodBye.php";
use Data\Traits\{Person, SayHello, sayGoodBye};
$person = new Person();
$person->goodBye("Joko");
$person->hello("Budi");
$person->name = "Eko";
var_dump($person);
Sesudah Function di Overriding
<?php
namespace Data\Traits;
trait SayGoodBye
{
public string $name;
public function goodBye (?string $name): void
{
if (is_null($name)) {
echo "Good bye" . PHP_EOL;
} else {
echo "Good Bye $name" . PHP_EOL;
}
}
}
trait SayHello
{
public string $name;
public function hello (?string $name): void
{
if (is_null($name)) {
echo "Hello" . PHP_EOL;
} else {
echo "Hello $name" . PHP_EOL;
}
}
}
trait HashName
{
public string $name;
}
trait CanRun
{
public abstract function run(): void;
}
class Person
{
use SayGoodBye, SayHello, HashName, CanRun;
public function run(): void
{
echo "Person $this->name is running" . PHP_EOL;
}
}
<?php
require_once "data/SayGoodBye.php";
use Data\Traits\{Person, SayHello, sayGoodBye};
$person = new Person();
$person->goodBye("Joko");
$person->hello("Budi");
$person->name = "Eko";
var_dump($person);
$person->run();
Trait Overriding
- Jika sebuah class memiliki parent class, yang memiliki function yang sama dengan function di trait, maka secara otomatis trait akan meng-override function tersebut
- Namun jika kita membuat function yang sama di class nya, maka secara otomatis kita akan meng-override function di trait
- Sehingga posisinya seperti ini ParentClass = override by => Trait = override by => ChildClass
Trait => Override by => ChildClass
<?php
namespace Data\Traits;
trait SayGoodBye
{
public string $name;
public function goodBye (?string $name): void
{
if (is_null($name)) {
echo "Good bye" . PHP_EOL;
} else {
echo "Good Bye $name" . PHP_EOL;
}
}
}
trait SayHello
{
public string $name;
public function hello (?string $name): void
{
if (is_null($name)) {
echo "Hello" . PHP_EOL;
} else {
echo "Hello $name" . PHP_EOL;
}
}
}
trait HashName
{
public string $name;
}
trait CanRun
{
public abstract function run(): void;
}
class Person
{
use SayGoodBye, SayHello, HashName, CanRun;
public function run(): void
{
echo "Person $this->name is running" . PHP_EOL;
}
public function goodBye(?string $name): void
{
echo "Good by in Person" . PHP_EOL;
}
public function hello(?string $name): void
{
echo "Good bye in Person" . PHP_EOL;
}
}
<?php
require_once "data/SayGoodBye.php";
use Data\Traits\{Person, SayHello, sayGoodBye};
$person = new Person();
$person->goodBye("Joko");
$person->hello("Budi");
$person->name = "Eko";
var_dump($person);
$person->run();
Parent Class => Override by => Trait
<?php
namespace Data\Traits;
trait SayGoodBye
{
public string $name;
public function goodBye (?string $name): void
{
if (is_null($name)) {
echo "Good bye" . PHP_EOL;
} else {
echo "Good Bye $name" . PHP_EOL;
}
}
}
trait SayHello
{
public string $name;
public function hello (?string $name): void
{
if (is_null($name)) {
echo "Hello" . PHP_EOL;
} else {
echo "Hello $name" . PHP_EOL;
}
}
}
trait HashName
{
public string $name;
}
trait CanRun
{
public abstract function run(): void;
}
class ParentPerson
{
public function goodBye(?string $name): void
{
echo "Good by in Person" . PHP_EOL;
}
public function hello(?string $name): void
{
echo "Good bye in Person" . PHP_EOL;
}
}
class Person extends ParentPerson
{
use SayGoodBye, SayHello, HashName, CanRun;
public function run(): void
{
echo "Person $this->name is running" . PHP_EOL;
}
}
<?php
require_once "data/SayGoodBye.php";
use Data\Traits\{Person, SayHello, sayGoodBye};
$person = new Person();
$person->goodBye("Joko");
$person->hello("Budi");
$person->name = "Eko";
var_dump($person);
$person->run();
Trait Visibility Override
- Selain melakukan override function di class, kita juga bisa melakukan override visibility function yang terdapat di trait
- Namun untuk melakukan ini tidak perlu membuat function baru di class, kita bisa gunakan secara sederhana ketika mengunakan trait nya
<?php
namespace Data\Traits;
trait SayGoodBye
{
public string $name;
public function goodBye (?string $name): void
{
if (is_null($name)) {
echo "Good bye" . PHP_EOL;
} else {
echo "Good Bye $name" . PHP_EOL;
}
}
}
trait SayHello
{
public string $name;
public function hello (?string $name): void
{
if (is_null($name)) {
echo "Hello" . PHP_EOL;
} else {
echo "Hello $name" . PHP_EOL;
}
}
}
trait HashName
{
public string $name;
}
trait CanRun
{
public abstract function run(): void;
}
class ParentPerson
{
public function goodBye(?string $name): void
{
echo "Good by in Person" . PHP_EOL;
}
public function hello(?string $name): void
{
echo "Good bye in Person" . PHP_EOL;
}
}
class Person extends ParentPerson
{
use SayGoodBye, SayHello, HashName, CanRun{
hello as private;
goodBye as private;
}
public function run(): void
{
echo "Person $this->name is running" . PHP_EOL;
}
}
<?php
require_once "data/SayGoodBye.php";
use Data\Traits\{Person, SayHello, sayGoodBye};
$person = new Person();
$person->goodBye("Joko");
$person->hello("Budi");
$person->name = "Eko";
var_dump($person);
$person->run();