【问题标题】:how trait and inheritence practically different?特质和继承实际上有何不同?
【发布时间】:2016-08-23 20:55:53
【问题描述】:

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

如果我要创建一个只有一些可重用逻辑的类,假设我们不需要多个特征。那么我们应该如何在这两者之间进行选择呢。

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

例如:

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

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

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

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

所以我想知道的是:

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

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

【问题讨论】:

  • traits 的全部意义在于让你从多个树中继承。如果你不需要它,那么定义 trait 是没有意义的。
  • @rjdown trait 并不代表一棵树,但我认为您想说的是继承不同的功能。但是在像上面的例子一样开始一个类的时候,当我们一开始只有一件事要继承或功能时,那么如何决定是特质还是继承呢?
  • 我认为你误读了我所说的。无论哪种方式,特征只是为了帮助(如手册所述)“以细粒度和一致的方式对功能进行分组”。同样,如果您不需要它,请不要使用它。
  • @rjdown 如何判断我是否需要它?我可以使用它,以便我总是可以拥有更多的特质或让其他东西继承的类。这样一来,特质听起来像是简单的选择,但这种心态将导致总是使用或特质。那么什么时候继承呢?
  • 如果您正在创建一个类并意识到您需要使用来自两个不同的其他类(具有不同的基类)的功能,那么您将使用一个特征。如果您正在创建一个将使用单个类的功能的类,那么首先考虑您是否需要一个新的。如果你这样做,只需延长。

标签: php oop inheritance traits


【解决方案1】:

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

在我看来,我只会将特征用于简单的接口实现,例如只有一个 getter 和 setter 的 ServiceManagerAwareInterface,以及一个特征 ServiceManagerAwareTrait,它将携带实现以避免在每个实现我的类中编写 getter 和 setter 逻辑界面。

这样,在使用接口隔离原则时会有所帮助。

【讨论】:

    【解决方案2】:

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

    在这两种情况下(即当您使用 trait 或扩展类时),您会在两个元素(分别为 trait 的消费者或超类型的子级)之间创建非常紧密的耦合。

    为什么这样不好?

    首先,您只能通过一种方式构建对象图。

    无论您做什么,MyController 将始终直接链接到 RestCrudTraitRestCrudController

    另外,这可能不是您的情况,对于特征和继承,您可能会使用您不希望类消耗特征或扩展父级的方法污染公共 API。


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

    在这种情况下,我肯定会选择继承,因为您需要解决环境带来的约束。

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

    不过,它已经向我证明,在代码中,您需要获取依赖项、将其分配给私有变量并仅公开您真正需要的内容,这通常是一个更好的主意,不仅而且主要是用于测试(创建低耦合)。

    【讨论】:

      猜你喜欢
      • 2012-08-03
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 2023-03-23
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多