特质与遗产有何不同?

时间:2016-04-28 21:27:35

标签: php oop inheritance traits

我知道抽象类可以有一个我们不想要的层次结构或树,所以我们使用trait更像是一次编写重复代码并包含在不同类中的方法。但是如果抽象类也没有层次结构呢?

如果我的课程只有一些可重用的逻辑,那么我们假设我们不需要多个特征。那么我们应该如何在这两者之间做出选择。

抽象类和特征中的方法都可以以相同的方式重写。简而言之,我们可以互相利用这两者。

例如:

class MyController{
   use RestCrudTrait;
   public function store(){
       //override here
   }
}

class MyController extends RestCrudController{
    public function store(){
       //override here
   }
}

我试过它们,它们可以以这种方式互换使用。我也放在这里控制器,它可以是模型或其他东西。那么究竟需要如何选择使用Trait或扩展类。

如果由于这些层次结构等原因导致继承不好,那么在继承时可以随时使用Trait吗?

所以我想知道的是:

  1. 这两者是否只是逻辑上不同,实际上可以做同样的事情,可以互换使用吗?

  2. 即使它们在逻辑上不同,那么应该如何在这两者之间做出选择呢?

2 个答案:

答案 0 :(得分:1)

我认为特质是一把严肃的双刃剑,一方面你可以像你说的那样复制代码,另一方面,你可以在这个过程中失去巨大的可读性。

在我看来,我只会使用traits进行简单的接口实现,比如一个只有getter和setter的ServiceManagerAwareInterface,以及一个特性ServiceManagerAwareTrait,它将进行实现以避免在每个实现我的类中编写getter和setter逻辑接口

以这种方式,它有助于使用接口隔离原则。

答案 1 :(得分:0)

如果我想重用代码,我实际上几乎总是选择继承或特性使用。虽然特征似乎是语言的一个很好的补充,但它们并不比在类本身内直接编写类new的属性更好,而不是从外部注入。

在这两种情况下(即使用特征或扩展类时),在两个元素(特征的使用者或超类型的子元素)之间创建了非常紧密的耦合。

为什么这么糟糕?

首先,您只能使用一种方法来构建对象图。

无论您做什么,MyController都会直接与RestCrudTraitRestCrudController相关联。

此外,这可能不是你的情况,有了traits和inheritance,你可能会使用你不希望类消耗特性或扩展父类的方法来对公共API进行策略。

无论如何,在大多数框架中,继承被深刻地使用(当自定义控制器扩展作为超类型的控件时),因为框架使用动态查找,如果可以访问路由或操作,则检查用户自制控制器的可用方法

在这样的场景中,我肯定会继承,因为你需要解决环境带来的约束。

如果您不限于任何约束,并且您想要的是简单的代码重用,而无需手动将组件注入到类中,并通过具有这些依赖关系的类的外观公开这些组件的方法,那么我会去对于一个特质。

尽管如此,我已经向我证明,你需要依赖一些代码,将它分配给私有变量并仅暴露你真正需要的代码,这通常是一个更好的主意,不仅仅是大多数用于测试(创建低耦合)。