PHP类型提示特征

ari*_*rik 25 php traits type-hinting

我有一个特点.为了创造力,让我们称之为特质Trait:

trait Trait{    
    static function treat($instance){    
        // treat that trait instance with care
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我还有一个使用这个特性的类,User.当尝试使用User实例调用treat时,一切正常.但我想输入提示,只有使用Trait的类的实例应该作为参数给出,如下所示:

static function treat(Trait $instance){...}
Run Code Online (Sandbox Code Playgroud)

但遗憾的是,这会导致致命的错误,该错误表明该函数期待Trait的一个实例,但是给出了一个User实例.这种类型的提示适用于继承和实现,但我如何键入提示特征?

Ved*_*eda 16

DaveRandom说,你不能.你不应该.您可能希望在其上实现接口和typehint.然后,您可以使用特征实现该接口.

  • 我不得不说我不同意这一点.我认为类型暗示特征将非常有用.Traits允许声明抽象方法,所以如果允许类型提示,它们可能比接口更有用,因为a)它们支持多重继承(如接口)和b)它们支持实现(如抽象类,_are_ type- hintable).由于PHP没有编译,因此类型提示几乎是关于抽象的最佳部分,因此特性并不像它们那样有用. (15认同)
  • @Rob,这会产生方法别名的问题(`使用myTrait {myMethod as newMethod;}`)以便发生碰撞.假设我有一个类myClass,其中包含一个方法"myMethod",特性myTrait提供了一些我想要添加到myClass的功能.我可以将函数"myMethod"别名为别的(在我的例子中为newMethod).现在B人看着它,看到我在myClass中使用myTrait,他认为他可以使用myClass和其他类似的类.但是这是错误的.在接口的情况下,我将被迫保持myMethod的意图相同. (8认同)
  • 我不得不承认,我不知道别名特征方法.但是,经过一些测试,抽象方法不能别名,因为[D](http://en.wikipedia.org/wiki/Dependency_inversion_principle)代表取决于抽象,B人不应该依赖于特征实现,而是而是他们的抽象方法,如在接口或抽象类中. (3认同)
  • 答案是正确的,您不想将特征用作类型。在类中将traits与关键字use一起使用的方式意味着您没有指示要创建的类型的任何信息,而只是在实现它。这基本上是复制并粘贴到该位置。确实很好,因为它使您实际上不必复制和粘贴并具有将要创建的重复项。通常,使用继承来避免复制和粘贴是很诱人的,但是这通常违反了正确继承的原则。 (2认同)

Tri*_*rey 9

对于将来在这里结束的人,我想详细说明吠陀的答案。

  1. 确实,您不能在 PHP 中将特征视为特征(具有讽刺意味),说您期望具有某些特征的对象只能通过接口(本质上是抽象特征的集合)才能实现
  2. 其他语言(例如 Rust)实际上鼓励使用特征进行类型提示

综上所述; 你的想法不是疯狂的!实际上,将特征视为该词的常识是很有意义的,而其他语言也是如此。由于某种原因,PHP 似乎卡在接口和特征之间。

  • 关于第 2 点:Rust 鼓励使用特征进行类型提示,但与 PHP 不同的是,Rust 不提供接口;Trait 是 Rust 中最接近接口的东西。 (3认同)