Can traits have properties & methods with private & protected visibility? Can traits have constructor, destructor & class-constants?

user9059272 picture user9059272 · Dec 9, 2017 · Viewed 12.5k times · Source

I've never seen a single trait where properties and methods are private or protected.

Every time I worked with traits I observed that all the properties and methods declared into any trait are always public only.

Can traits have properties and methods with private and protected visibility too? If yes, how to access them inside a class/inside some other trait? If no, why?

Can traits have constructor and destructor defined/declared within them? If yes, how to access them inside a class? If no, why?

Can traits have constants, I mean like class constants with different visibility? If yes, how to inside a class/inside some other trait? If no, why?

Special Note : Please answer the question with working suitable examples demonstrating these concepts.

Answer

Hakan SONMEZ picture Hakan SONMEZ · Dec 9, 2017

Traits can have properties and methods with private and protected visibility too. You can access them like they belong to class itself. There is no difference.

Traits can have a constructor and destructor but they are not for the trait itself, they are for the class which uses the trait.

Traits cannot have constants. There is no private or protected constants in PHP before version 7.1.0.

trait Singleton{
    //private const CONST1 = 'const1'; //FatalError
    private static $instance = null;
    private $prop = 5;

    private function __construct()
    {
        echo "my private construct<br/>";
    }

    public static function getInstance()
    {
        if(self::$instance === null)
            self::$instance = new static();
        return self::$instance;
    }

    public function setProp($value)
    {
        $this->prop = $value;
    }

    public function getProp()
    {
        return $this->prop;
    }
}

class A
{
    use Singleton;

    private $classProp = 5;

    public function randProp()
    {
        $this->prop = rand(0,100);
    }

    public function writeProp()
    {
        echo $this->prop . "<br/>";
    }
}

//$a1 = new A(); //Fatal Error too private constructor
$a1 = A::getInstance();
$a1->writeProp();
echo $a1->getProp() . "<br/>";
$a1->setProp(10);
$a1->writeProp();
$a1->randProp();
$a1->writeProp();
$a2 = A::getInstance();
$a2->writeProp();
$a2->randProp();
$a2->writeProp();
$a1->writeProp();