Search code examples
phpclassabstracttraitsphp-5.4

Why Traits cannot be instantiated directly?


While testing for traits in PHP I was a bit confused why traits were introduced. I did some minor experiment. First I called trait methods directly in a class

<?php

trait HelloWorld {
    public function sayHello() {
        echo 'Hello World!';
    }
}

class TheWorldIsNotEnough {
    use HelloWorld;
    public function sayHellos() {
        $o = new HelloWorld();
        $o->sayHello();
    }
}

$o = new TheWorldIsNotEnough();
$o->sayHellos();

?>

I got an error

Fatal error: Cannot instantiate trait HelloWorld in C:\xampp\htdocs\test.php on line 35

But when I did this

<?php

trait HelloWorld {
    public function sayHello() {
        echo 'Hello World!';
    }
}
class MyHelloWorld {
    use HelloWorld;
}
class TheWorldIsNotEnough {
    use HelloWorld;
    public function sayHellos() {
        $o = new MyHelloWorld();
        $o->sayHello();
    }
}

$o = new TheWorldIsNotEnough();
$o->sayHellos();

?>

i was able to call the trait method and the result displayed "Hello World! ". So what is advantage of using Traits and how is it different from abstract classes? Kindly help me understand the usage. Thanks.


Solution

  • Traits should not be instantiated. They are simply code parts, that you can reuse in your classes by useing them. You can imagine, that a trait code expands and becomes a part of your class. It is even being sad, that:

    Traits are essentially language assisted copy and paste.

    So your example should work like this:

    <?php
    
    trait HelloWorld {
        public function sayHello() {
            echo 'Hello World!';
        }
    }
    
    class TheWorldIsNotEnough {
        use HelloWorld;
    
        public function sayHellos() {
            // your trait defines this method, so now you can    
            // think that this method is defined in your class directly
            $this->sayHello(); 
        }
    }
    
    $o = new TheWorldIsNotEnough();
    $o->sayHellos();
    
    //or simply
    $o->sayHello();
    ?>