PHP 中 Trait 和抽象类的区别

Posted

技术标签:

【中文标题】PHP 中 Trait 和抽象类的区别【英文标题】:Difference between Trait and an Abstract Class in PHP 【发布时间】:2017-01-20 20:21:05 【问题描述】:

我最近在 php 中遇到了Traits,我正在尝试理解它们。在我的研究中,我偶然发现了这个 Stack Overflow 问题:Traits vs. Interfaces。接受的答案提到以下内容:

接口定义了实现类必须的一组方法 实施。

当使用特征时,方法的实现随之而来 也是——这不会发生在接口中。

到目前为止一切都很好,但这听起来就像接口和抽象类之间的区别对我来说。所以这对我提出了一个后续问题:

PHP 中的 Trait 和 Abstract Class 有什么区别?

我知道我只能从一个抽象类扩展,另一方面可以使用任意数量的特征。但这真的是唯一的区别吗?我仍然不完全了解特征及其用途。

【问题讨论】:

也许有帮助:***.com/a/20866390/3840840 【参考方案1】:

Traits 允许您在类之间共享代码而不会强迫您进入特定的类层次结构。假设你希望你的所有类都有方便的实用方法foo($bar);没有特质你有两种选择:

在每个类中使用代码冗余单独实现它 从通用(抽象)祖先类继承

两种解决方案都不理想,各有不同的权衡取舍。代码冗余显然是不可取的,从一个共同的祖先继承会使您的类层次结构设计不灵活。

Traits 通过让您在每个类可以单独“导入”的 trait 中实现 foo($bar) 来解决这个问题,同时仍然允许您根据业务逻辑要求而不是语言需求来设计类层次结构。

【讨论】:

所以如果我做对了,基本上认为特征在几个没有任何关系的类中使用相同的代码? 是的,完全正确。把它想象成你可以用来将一个类从(组合)组合在一起的一些零碎的东西。根据您的应用中代码可重用性的好坏,您可以将所有内容都实现为一个 trait,然后只需将少数几个 trait 组合成各种配置的实际类。 你说它像帮手吗? @Jeremy 这可能是最常见的用例,但它本身就太狭窄了。如上所述,如果这对您的情况有意义的话,您可以完全根据特征组成整个类。 您也可以将它们与接口结合使用,例如在接口中定义一些方法并为实现提供特征,这样您的实现比抽象类更灵活(因为它不限于单一类型)【参考方案2】:

不完全是……让我们为此引用官方文档:

Trait 类似于类,但仅用于分组 以细粒度和一致的方式实现功能。这不可能 自己实例化一个 Trait。它是对传统的补充 继承并使行为的水平组合成为可能;那是, 无需继承即可应用类成员。

因此,Traits 用于组合目的,以使类能够执行某些逻辑/行为。如果您从另一个/抽象类继承,这通常是出于多态性的目的,并且您会获得不同的继承/类层次结构,这可能是可取的,也可能不是。

我认为这完全取决于上下文、架构以及您到底想做什么。

【讨论】:

很好的解释。

以上是关于PHP 中 Trait 和抽象类的区别的主要内容,如果未能解决你的问题,请参考以下文章

PHP 进阶之 抽象类(abstract)接口(interface)Trait(特征)

PHP之Trait详解

php抽象类和接口的区别

PHP 特性之 trait

PHP 特性之 trait

Scala - 特质Trait