手册目录: 语言参考---类与对象---Trait
参考详情: https://secure.php.net/manual/zh/language.oop5.traits.php
评论部分:
1. by Safak Ozpinar / safakozpinar@gmail
与继承不同,如果trait中包含有静态属性,那么每一个use trait的类将是相互独立的.如:
Example using parent class:
class TestClass {
public static $_bar;
}
class Foo1 extends TestClass { }
class Foo2 extends TestClass { }
Foo1::$_bar = 'Hello';
Foo2::$_bar = 'World';
echo Foo1::$_bar . ' ' . Foo2::$_bar; // Prints: World World
?>
Example using trait:
trait TestTrait {
public static $_bar;
}
class Foo1 {
use TestTrait;
}
class Foo2 {
use TestTrait;
}
Foo1::$_bar = 'Hello';
Foo2::$_bar = 'World';
echo Foo1::$_bar . ' ' . Foo2::$_bar; // Prints: Hello World
?>
2. by Stefan W
目前use有三种用法,分别是use namesapce,use trait和匿名函数中的use变量,而对于use namesapce和use trait,有几点不同的地方,use namespace是类外,use trait是类内,它们对路径的解析也是有差异的,如下:
namespace Foo\Bar;
use Foo\Test; // means \Foo\Test - the initial \ is optional
?>
use trait是针对目前所在的namesapce
namespace Foo\Bar;
class SomeClass {
use Foo\Test; // means \Foo\Bar\Foo\Test
}
?>
3. by [email protected]
__class__将返回trait代码所在类的类名,而非调用trait内部方法的类的类名,如下:
trait TestTrait {
public function testMethod() {
echo "Class: " . __CLASS__ . PHP_EOL;
echo "Trait: " . __TRAIT__ . PHP_EOL;
}
}
class BaseClass {
use TestTrait;
}
class TestClass extends BaseClass {}
$t = new TestClass();
$t->testMethod();
//Class: BaseClass
//Trait: TestTrait
4. by qeremy(!)gmail
final关键字在trait中不管用,与继承和抽象是不同的,如:
trait Foo {
final public function hello($s) { print "$s, hello!"; }
}
class Bar {
use Foo;
// Overwrite, no error
final public function hello($s) { print "hello, $s!"; }
}
abstract class Foo {
final public function hello($s) { print "$s, hello!"; }
}
class Bar extends Foo {
// Fatal error: Cannot override final method Foo::hello() in ..
final public function hello($s) { print "hello, $s!"; }
}
?>
要实现final效果,你可以通过多重继承来实现,如:
trait Foo {
final public function hello($s) { print "$s, hello!"; }
}
class Bar {
use Foo;
// Overwrite, no error
//public function hello($s) { print "hello, $s!"; }
}
class a extends Bar{
public function hello($s) { print "hello, $s!"; }
}
a::hello("he"); // Fatal error:Cannot override final method Bar::hello()
?>
5. by [email protected]
另外一个trait与继承的不同,trait中可以访问use它的类中的方法和属性,并且不受访问限制范围的限制.如:
trait MyTrait
{
protected function accessVar()
{
return $this->var;
}
}
class TraitUser
{
use MyTrait;
private $var = 'var';
public function getVar()
{
return $this->accessVar();
}
}
$t = new TraitUser();
echo
6. by [email protected]
当trait中定义了static 方法的时候,可以使用::直接调用,如:
trait Foo {
function bar() {
return 'baz';
}
}
echo Foo::bar(); \\output baz
?>
同时这种方式也适用于trait中定义static 变量.
7. by Osiris RD
当trait名与类名相同时,将产生fatal error,如:
trait samara{}
class samara{
use samara; // fatal error redeclare class samara
}