在PHP中测试trait的时候,我有点困惑为什么要引入trait,我做了一些小实验。
<?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();
?>
字符串
我得到一个错误
Fatal error: Cannot instantiate trait HelloWorld in C:\xampp\htdocs\test.php on line 35
型
但当我这么做的时候
<?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();
?>
型
我可以调用trait方法,结果显示“Hello World!“。那么使用Trait的好处是什么?它与抽象类有什么不同?请帮助我理解用法。谢谢。
4条答案
按热度按时间56lgkhnf1#
Traits
不应该被示例化。它们只是代码部分,你可以通过use
ing它们在你的类中重用。你可以想象,一个trait
代码扩展并成为你的类的一部分。它甚至是可悲的,那:特征本质上是语言辅助的复制和粘贴。
所以你的例子应该是这样的:
字符串
yduiuuwa2#
感谢所有贴出答案的人,但我真正在寻找的答案是我在大量研究后得到的。我的问题是是什么使Traits不同于现有的方法,如抽象类,继承等。在类内部调用时示例化它是可以的,但最大的区别是我们可以通过这种方式在类中包含多个trait
字符串
在冲突的情况下,当两个类中存在相同的方法时,我们想使用class2中的方法,我们这样做
型
即使是traits也可以有多个traits以这种方式定义:
型
与继承不同,如果trait具有静态属性,则使用该trait的每个类都具有这些属性的独立示例。http://php.net/manual/en/language.oop5.traits.php#107965
traits与继承的另一个区别是,traits中定义的方法可以访问它们所使用的类的方法和属性,包括私有方法和属性。http://php.net/manual/en/language.oop5.traits.php#109508
与接口实现不同的是,所有traits方法都可以访问,而无需再次定义它们。
8fq7wneg3#
好吧,这可能不是实现它的方法,但我找到了一种方法来使用Traits,以及为什么在某些情况下它对我的项目更好。它们是类的一种扩展。如果你经常使用CakePHP,这些Traits让我想起了模型的行为或控制器的组件。只要查找一下:-)
抽象类略有不同,因为你可以像这样使用它来继承:
字符串
trait更像是类的扩展。我在MVC框架中使用Traits来扩展类,并以这种方式记录日志:
型
这是非常方便的,因为我在每个类中使用它,我不需要再次编写所有那些必须连接到数据库并生成SQL查询的行。而且因为我在整个MVC框架中有很多继承,所以我不需要将Logger作为父类包含在内。只需将它与“use”-关键字一起放置到任何应该能够将loginfo发送到数据库的类中。
同样的事情也适用于我的调试消息,我只是写这样的东西:
型
我的座右铭是:“善有善报,恶有恶报”。
0sgqnhkj4#
Abstract
和Trait
类之间唯一的共同点是,不可能单独示例化a Trait/an Abstract
。但它们的目的是不同的。
Trait
只是为了将功能分组在一个精细的它是为了减少单一继承的一些限制,使开发人员能够在不同类层次结构中的几个独立类中使用reuse sets of methods freely
,而Abstract
类只是为了提供一种模板来继承,并强制继承类实现抽象方法.