内容简介:traits是PHP5.4新进入的特性,其目的就是解决PHP的类不能多继承的问题。Trait会覆盖继承的方法,当前类会覆盖Trait方法。即 继承的方法 < Traits方法 < 当前类方法,为了对使用的类施加强制要求,trait 支持抽象方法的使用。
概述
traits是 PHP 5.4新进入的特性,其目的就是解决PHP的类不能多继承的问题。 Traits不是类!不能被实例化。 可以理解为一组能被不同的类都能调用到的方法集合。只需要在类中使用关键词use引入即可,可引入多个Traits,用','隔开。
简单使用
trait myTrait{ public $traitPublic = 'public'; protected $traitProtected = 'protected'; function traitMethod1() { echo __METHOD__,PHP_EOL; } function traitMethod2() { echo __METHOD__,PHP_EOL; } } class myClass{ use myTrait; } $obj = new myClass(); $obj->traitMethod1(); $obj->traitMethod2(); // ↓↓ 只能调用public的属性和方法; protected以及private只供在traits内部自己调用; echo $obj->traitPublic;
优先级问题
Trait会覆盖继承的方法,当前类会覆盖Trait方法。即 继承的方法 < Traits方法 < 当前类方法,
trait A{ public $var1 = 'test'; public function test() { echo 'A::test()'; } public function test1() { echo 'A::test1()'; } } class B{ public function test() { echo 'B::test()'; } public function test1() { echo 'B::test1()'; } } class C extends B{ use A; public function test() { echo 'c::test()'; } } $c = new C(); $c->test(); //c::test() Traits方法 < 当前类方法 $c->test1(); //A::test1() 继承的方法 < Traits方法
多个Trait冲突问题
- 如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。
- 为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。
- 可用as操作符将其中一个冲突方法另起名;
trait A{ public function test() { echo 'A::test()'; } } trait B{ public function test() { echo 'B::test()'; } } class C{ use A , B { B::test insteadof A; //明确B替代A B::test as t; //或者另起一个名字 } } $c = new C(); $c->test(); //B::test() $c->t(); //B::test() 可以用as另起名
as可用来修改方法访问控制
trait HelloWorld{ public function sayHello() { echo 'Hello World!'; } } // 修改 sayHello 的访问控制 class A{ use HelloWorld { sayHello as protected; } } // 给方法一个改变了访问控制的别名 // 原版 sayHello 的访问控制则没有发生变化 class B{ use HelloWorld { sayHello as private myPrivateHello; } } $a = new A(); $a->sayHello(); //Fatal error: Call to protected method A::sayHello() from context ''; 改变了sayHello的访问规则; $b = new B(); $b->sayHello(); //Hello World!
Trait中使用Trait
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(); // Hello World!
Trait中抽象成员
为了对使用的类施加强制要求,trait 支持抽象方法的使用。
trait Hello{ public function sayHelloWorld() { echo 'Hello' . $this->getWorld(); } abstract public function getWorld(); } class MyHelloWorld{ private $world; use Hello; // 必须要实现trait里面的抽象方法,否则Fatal error: Class MyHelloWorld contains 1 abstract method and must therefore be declared abstract or implement the remaining methods public function getWorld() { return $this->world; } public function setWorld($val) { $this->world = $val; } } $obj = new MyHelloWorld(); echo $obj->setWorld();
Trait中静态成员
Traits 可以被静态成员静态方法定义,不可以直接定义静态变量,但静态变量可被trait方法引用.
# 静态属性; 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 $o->inc(); // echo 2; $p = new C2(); $p->inc(); // echo 1 # 静态方法 trait StaticExample { public static function doSomething() { echo 'Doing something'; } } class Example { use StaticExample; } Example::doSomething(); // Doing something
Trait中属性
trait PropertiesTrait{ public $x = 1; } class PropertiesExample{ use PropertiesTrait; } $example = new PropertiesExample; echo $example->x; // 1
如果 trait 定义了一个属性,那类将不能定义同样名称的属性,否则会产生一个错误。如果该属性在类中的定义与在 trait 中的定义兼容(同样的可见性和初始值)则错误的级别是 E_STRICT,否则是一个致命错误。
trait PropertiesTrait { public $same = true; public $different = false; } class PropertiesExample { use PropertiesTrait; public $same = true; // Strict Standards public $different = true; // 致命错误 }
参考链接:
以上所述就是小编给大家介绍的《【modernPHP专题(5)】类多继承的替代方案Traits》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
- PHP类继承、接口继承关系概述
- 面向对象:理解 Python 类的单继承与多继承
- java入门第二季--继承--java中的继承初始化顺序
- 前端基本功(七):javascript中的继承(原型、原型链、继承的实现方式)
- 组合还是继承,这是一个问题?——由模式谈面向对象的原则之多用组合、少用继承
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
首席产品官2 从白领到金领
车马 / 机械工业出版社 / 79元
《首席产品官》共2册,旨在为产品新人成长为产品行家,产品白领成长为产品金领,最后成长为首席产品官(CPO)提供产品认知、能力体系、成长方法三个维度的全方位指导。 作者在互联网领域从业近20年,是中国早期的互联网产品经理,曾是周鸿祎旗下“3721”的产品经理,担任CPO和CEO多年。作者将自己多年来的产品经验体系化,锤炼出了“产品人的能力杠铃模型”(简称“杠铃模型”),简洁、直观、兼容性好、实......一起来看看 《首席产品官2 从白领到金领》 这本书的介绍吧!