用 PHP 中的类扩展特征?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10056520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:16:54  来源:igfitidea点击:

Extend Traits with Classes in PHP?

phpooptraits

提问by Meglio

Why we are not allowed to extend Traits with Classes in PHP?

为什么我们不允许在 PHP 中使用类扩展 Traits?

For example:

例如:

Trait T { }

Class C use T {}
/* or */
Class C extends T {}

Is there any potential conflict for such syntax? I do not think so.

这种语法是否存在潜在冲突?我不这么认为。

回答by mrlee

The PHP manual states thus:

PHP 手册指出:

Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.

Traits 是一种在单继承语言(如 PHP)中代码重用的机制。Trait 旨在通过使开发人员能够在位于不同类层次结构中的多个独立类中自由重用方法集来减少单继承的一些限制。Traits 和类组合的语义以一种降低复杂性的方式定义,并避免了与多重继承和 Mixin 相关的典型问题。

If you're looking to extend a trait, then it should probably be a class. If you have a set of methods in one class that you want to use in others, but it feels inappropriate to extend the class (eg. class Animal extends Vehicle), then in PHP 5.4 it could work well as a trait.

如果你想扩展一个特性,那么它可能应该是一个类。如果您在一个类中有一组方法想要在其他类中使用,但感觉不适合扩展该类(例如class Animal extends Vehicle),那么在 PHP 5.4 中它可以很好地作为 trait。

To answer the question more directly, you don't 'extend' a trait, but you can create traits which themselves use other traits. As per the PHP manual:

为了更直接地回答这个问题,您不“扩展”一个特征,但您可以创建自身使用其他特征的特征。根据 PHP 手册:

trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World!';
    }
}

trait HelloWorld {
    use Hello, World;
}

class MyHelloWorld {
    use HelloWorld;
}

You can consider this to be a way to maintain your traits in logical groups, and to introduce some modularity.

您可以认为这是一种在逻辑组中维护特征并引入一些模块化的方法。

Edit: having seen some of the comments, I think it's worthwhile to note that using a trait in a base class also means that trait is in any class that extends it, and the trait's functions take precedence over the base class'. Putting it in the child class would merely make the trait's functions unavailable to the parent/base class.

编辑:看过一些评论后,我认为值得注意的是,在基类中使用 trait 也意味着 trait 在扩展它的任何类中,并且 trait 的函数优先于基类'。将它放在子类中只会使 trait 的函数对父类/基类不可用。

Parent > Trait > Child

http://php.net/manual/en/language.oop5.traits.php

http://php.net/manual/en/language.oop5.traits.php

回答by andrewtweber

You can extend traits somewhat. Expanding on mrlee's answer, when you usea trait you can rename its methods.

您可以稍微扩展特征。扩展mrlee的答案,当你use有一个特质时,你可以重命名它的方法。

Say for example you have a "parent" trait that was defined by your framework:

例如,假设您有一个由您的框架定义的“父”特征:

trait FrameworkTrait {
    public function keepMe() {
        // Framework's logic that you want to keep
    }

    public function replaceMe() {
        // Framework's logic that you need to overwrite
    }
}

Simply pull in the parent trait, rename its replaceMemethod to something else, and define your own replaceMemethod.

只需拉入父特征,将其replaceMe方法重命名为其他名称,然后定义您自己的replaceMe方法。

trait MyTrait {
    use FrameworkTrait {
        FrameworkTrait::replaceMe as frameworkReplaceMe;
    }

    public function replaceMe() {
        // You can even call the "parent" method if you'd like:
        $this->frameworkReplaceMe();

        // Your logic here
    }
}

And then in your class:

然后在你的课堂上:

class MyClass {
    use MyTrait;
}

Now objects of this class can do this:

现在这个类的对象可以这样做:

$obj = new MyClass();

$obj->keepMe();             // calls "parent" trait
$obj->replaceMe();          // calls "child" trait
$obj->frameworkReplaceMe(); // calls "parent" trait

回答by John Conde

Only classes can be extended. Traits are notclasses. They can be used/included by classes but are not classes themselves. If you think a trait needs to be extended then it probably should be a class, probably an abstract one, and not a trait.

只能扩展类。特质不是阶级。它们可以被类使用/包含,但不是类本身。如果你认为一个 trait 需要扩展,那么它可能应该是一个类,可能是一个抽象类,而不是一个 trait。