Mengenal Trait di PHP
Trait adalah mekanisme untuk penggunaan kembali kode dalam single inheritance. Trait dimaksudkan untuk mengurangi beberapa keterbatasan dari turunan tunggal dengan memungkinkan pengembang untuk menggunakan kembali serangkain fungsi-fungsi secara bebas pada beberapa klas yang independen yang hidup dalam hirarki klas yang berbeda.
Trait mirip dengan klas, hanya saja trait dimaksudkan untuk mengelompokan fungsi menjadi kecil dan konsisten. Kita tidak bisa meng-instansi trait pada dirinya sendiri tetapi kita bisa menggunakannya tanpa harus menurukannya(inheritance).
Daftar Isi:
Precedence Trait Multiple Resolusi Konflik Merubah visibility metode Trait disusun dari Trait Anggota Trait Abstract Anggota Static Trait Property
Contoh trait:
<?php
namespace app\traits;
trait Foo
{
public function hello()
{
return 'Hello';
}
}
Untuk menggunakan trait pada klas kita cukup gunakan keyword use
didalam definisi klas.
<?php
class User
{
use \app\traits\Foo;
// kita dapat menggunakan fungsi dari trait Foo
// secara langsung menggunakan $this
public function world()
{
echo $this->hello() . ' world!';
}
}
Hal mendahului/ Precedence
Anggota turunan dari klas dasar ditumpuki oleh anggota yang disisipi oleh Trait. Urutan precedence adalah bahwa member dari klas saat ini ditumpuk oleh trait yang disisipkan.
Contoh
Fungsi turunan dari klas dasar (Base
) ditumpuk oleh fungsi yang disisipkan pada klas MyHelloWorld
yaitu dari trait SayWorld
. Aturan ini akan sama untuk fungsi yang didefinisikan di dalam klas MyHelloWorld
.
<?php
class Base
{
public function sayHello()
{
echo 'Hello ';
}
}
trait SayWorld
{
public function sayHello()
{
echo 'World!';
}
}
class MyHelloWorld extends Base
{
use SayWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
// output:
// World
Contoh lain dari urutan precedence
<?php
trait HelloWorld
{
public function sayHello()
{
echo 'Hello World!';
}
}
class DuniaTidakCukup
{
use HelloWorld;
public function sayHello()
{
echo 'Halo Dunia!';
}
}
$o = new DuniaTidakCukup();
$o->sayHello();
Contoh di atas akan menghasilkan keluaran:
Halo Dunia!
Trait Multiple
Multiple trait dapat disisipkan ke dalam klas dengan mendaftarkannya pada statemen use
, dipisahkan dengan koma.
<?php
trait Hello
{
public function sayHello()
{
echo 'Hello ';
}
}
trait World
{
public function sayWorld()
{
echo 'World';
}
}
class MyHelloWorld
{
use Hello, World;
public function sayExclamationMark()
{
echo '!';
}
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
Resolusi Konflik
Jika dua Trait disisipkan dengan nama yang sama maka akan terjadi kesalahan fatal, jika masalah tidak dipecahkan secara eksplisit. Untuk memecahkan konflik penamaan antara Trait pada klas yang sama, operator insteadof
diperlukan untuk memilih tepat satu dari method yang konflik. Karena hal ini hanya boleh membuat satu pengecualian, operator as
dapat digunakan untuk menambah alias ke suatu method. Perlu dicatat bahwa operator as
tidak merubah nama method dan tidak mempengaruhi method lain.
Contoh
Pada contoh ini, klas Talker
menggunakan trait A
dan B
. Karena trait A
dan B
memiliki konflik, maka klas ini akan perlu mendefinisikan penggunaan method smallTalk
dari trait B
dan method bigTalk
dari trait A
.
Klas Alias_Talker
menggunakan operator as
untuk dapat menggunakan method bigTalk
dari trait B
dengan nama alias talk
.
<?php
trait A
{
public function smallTalk()
{
echo 'a';
}
public function bigTalk()
{
echo 'A';
}
}
trait B
{
public function smallTalk()
{
echo 'b';
}
public function bigTalk()
{
echo 'B';
}
}
class Talker
{
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
}
}
class Aliased_Talker
{
use A, B {
B::smallTalk insteadof A;
A::bigTalk insteadof B;
B::bigTalk as talk;
}
}
Merubah visibility metode
Dengan menggunakan syntax as
method pada trait dapat dirubah visibilitynya pada klas yang menggunakan trait.
Contoh
<?php
trait HelloWorld
{
public function sayHello()
{
echo 'Hello world!';
}
}
// Merubah visibility fungsi sayHello
class MyClass1
{
use HelloWorld { sayHello as protected; }
}
// Alias method dengan perubahan visibility
// Visibility sayHello tetap tidak berubah
class MyClass2
{
use HelloWorld { sayHello as private myPrivateHello; }
}
Trait disusun dari Trait
Seperti pada klas yang dapat menggunakan trait, jadi trait juga dapat menggunakan trait lain. Dengan menggunakan satu atau lebih trait di dalam definisi trait, trait ini dapat disusun sebagian atau semuanya dari anggota yang mendefinisikan pada trait lain.
Contoh
<?php
trait Hello
{
public function sayHello()
{
echo 'Hello';
}
}
trait World
{
public function sayWorld()
{
echo 'World';
}
}
trait HelloWorld
{
use Hello, World;
}
class MyHelloWorld
{
use HelloWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
Anggota Trait Abstract
Trait mendukung penggunaan abstract method untuk memaksa kebutuhan pada class yang menggunakan trait.
Contoh abstract method
<?php
trait Hello
{
public function sayHelloWorld()
{
echo 'Hello' . $this->getWorld();
}
abstract public function getWorld();
}
class MyHelloWorld
{
private $world;
use Hello;
public function getWorld()
{
return $this->world;
}
public function setWorld($val)
{
$this->world = $val;
}
}
Anggota Static Trait
Trait dapat mendefinisikan static property dan static method
Contoh static variabel
<?php
trait Counter
{
public function inc()
{
static $c = 0;
$c = $c + 1;
echo "$c\n";
}
}
class C1
{
use Counter;
}
class C2
{
use Counter;
}
$o = new C1();
$o->inc(); // echo 1
$p = new C2();
$p->inc(); // echo 1
Contoh static method
<?php
trait StaticExample
{
public static function doSomething()
{
return 'Doing Something';
}
}
class Example
{
use StaticExample;
}
Example::doSomething();
Property
Di dalam Trait kita juga dapat mendefinisikan property
sama seperti pada klas.
Contoh
trait PropertiesTrait
{
public $x = 1;
}
class PropertiesExample
{
use PropertiesTrait;
}
$ex = new PropertiesExample();
$ex->x;
sekian.
sumber: php.net