<
Neerav Mehta
Founder & CEO
HondaAccord
class implement the ContainerInterface
because it has a trunk. As a result, we could use HondaAccord
class wherever ContainerInterface
is used. But the code looks ugly! Since interfaces can't provide implementation, the methods putItTrunk
and takeFromTrunk
needed to be implemented in both the classes. This prevents code reuse. That's where traits come to the rescue. Traits help you embed a set of properties and methods in several independent classes that could be living in different hierarchies. Here is the ContainerTrait
trait created in ContainerTrait.php
file./**
* ContainerTrait trait.
*/
trait ContainerTrait {
// Stuff in the trunk.
public $stuff;
/**
* Put stuff in trunk.
*
* @param mixed $stuff
* Stuff to be put in the trunk.
*/
public function putInTrunk($stuff) {
$this->stuff = $stuff;
}
/**
* Take stuff out from the trunk.
*
* @return mixed
* Stuff returned from the trunk.
*/
public function takeFromTrunk() {
$stuff = $this->stuff;
unset($this->stuff);
return $stuff;
}
Now we could modify Container
and HondaAccord
classes as follows:
require_once 'ContainerInterface.php';
require_once 'ContainerTrait.php';
/**
* Class Container
*/
class Container implements ContainerInterface {
use ContainerTrait;
}
require_once 'ContainerInterface.php';
require_once 'ContainerTrait.php';
/**
* Class HondaAccord
*/
class HondaAccord extends Vehicle implements ContainerInterface {
use ContainerTrait;
}
Notice that in both the files, we are using use ContainerTrait;
to include ContainerTrait
in each of the classes. Just by using this statement, both HondaAccord
and Container
class can now use the properties defined in the ContainerTrunk
as its own. As an example, add the following code to the end of Vehicle.php
.
$yourCar = new HondaAccord('white');
$yourCar->putInTrunk('umbrella');
echo "Things taken out from the trunk: " . $yourCar->takeFromTrunk() . "\n";
On executing the Vehicle.php
file, you'll see the following output:
$ php Vehicle.php
Things taken out from the trunk: umbrella
Note that we didn't have to define the methods putInTrunk()
and takeFromTrunk()
, and the property $stuff
in HondaAccord
class but we could still use these since HondaAccord
class used ContainerTrait
. These methods and properties will be available in whichever class we use this trait. This makes for very efficient code reuse. If you followed everything till this point, then you understand traits well enough to be able to follow Drupal 8 code. PHP spec and rules about traits are quite extensive but those are outside the scope of this post. If you want to read them, go to http://php.net/manual/en/language.oop5.traits.php.
When to use traits? Use traits when you want a lot of independent classes to have the same method or property without duplicating code in all these classes. In this post, we saw how using ContainerTrait
helped us reduce code in Container
and HondaAccord
classes. Another example is ColorTrait
. You could define the property $color
and methods getColor()
and setColor()
. This trait could be used in any class which tries to mimic a real object having color.
Neerav Mehta
Neerav Mehta is the Founder & CEO of Red Crackle. With sterling qualities, Neerav’s technological acumen is firing a generation of progressive companies on the digital path. With an undergraduate degree in Electrical Engineering from India's most prestigious institution IIT Bombay and having spent seven years developing and contributing to the launch of AMD's innovative line of computer products, Neerav founded Red Crackle where he is lauded for his dynamic and innovative genius.
Let’s get you started!