PHP 接口有属性吗?

Posted

技术标签:

【中文标题】PHP 接口有属性吗?【英文标题】:Do PHP interfaces have properties? 【发布时间】:2011-02-14 23:09:35 【问题描述】:

php 中的接口有属性,还是只有方法?

【问题讨论】:

(参考) php.net/manual/en/language.oop5.interfaces.php 这个问题是一个合理的问题,可以将类的公共属性视为该类公共接口的一部分,并且可能希望强制实现接口的类使某个命名可用的财产。但是你不能——所以你只需要在接口中有 getProperty() setProperty() 方法——这不是一件坏事,因为每个人都知道公共属性是邪恶的(我们都知道不是吗?是吗?不是吗?) 【参考方案1】:

这取决于您所说的“属性”是什么意思。如果您的意思是实际字段,那么不,他们没有。如果您指的是诸如 C# 中的属性,那么是的,它们可以(因为属性访问器无论如何都是访问器方法的严格语法糖)。事件也是如此(当然,在每种情况下,都没有为 get/setadd/remove 访问器指定实现)。

更新:由于 PHP 没有 get/set 访问器意义上的属性,因此您的问题的答案是否定的。接口不能携带自己的数据/状态。

【讨论】:

常量在某些圈子中被视为数据。 ymmv @nickl- 那些圈子很疯狂,因为状态会改变,而常量不会。【参考方案2】:

PHP 接口可以有常量,但不能有属性(实例变量)。如果你不需要修改你的“属性”,你可以使用一个常量来代替。

【讨论】:

【参考方案3】:

PHP 中的接口只能包含没有方法主体的公共方法签名。它们也可能包含常量。但就是这样。没有别的了。

见http://www.php.net/manual/en/language.oop5.interfaces.php

接口使用 interface 关键字定义,与标准类相同,但没有定义其内容的任何方法。 […] 接口中声明的所有方法都必须是公共的,这是接口的本质。 […] 接口可以有常量。接口常量的工作方式与类常量完全相同,只是它们不能被继承它的类/接口覆盖。

【讨论】:

【参考方案4】:

在接口中需要属性的 [有效] 原因是指定 DTO 类具有特定方面,例如IOrderable OrderDate, OrderStatus , IDeliverable DeliveryAddress, Route, ... 等。切面可用于许多 DTO,例如销售订单、工作订单、销售发票等 DTO 类可以支持多个方面,即在数据类(但不是代码类)中需要的多重继承。此后,确保 DTO 的客户端可以通过该方面(接口契约)查看 DTO。此模式符合 SOLID 的所有 5 项原则。

在 PHP 中,最接近接口属性的是特征 http://php.net/manual/en/language.oop5.traits.php。与接口类似,trait 不能被实例化,但是可以直接在类中使用而不用实现它们。

【讨论】:

特征绝不类似于接口“属性” - 也根本与接口非常相似。这是不正确的 接口是类方法的蓝图,特征是可以在类之间轻松共享的一组方法/属性,无需使用继承或依赖注入。【参考方案5】:

您可以在 DocBlock 中为接口声明属性。然后,IDE 将提示接口的这些属性(PhpStorm 会),但这不会强制在实现类中实际实现这些字段。比如

/**
 * @property string $password
 * @property string $username
 */
interface IUserDocument




【讨论】:

嗨,这很有趣。我试图添加文档注释,我应该在哪里找到 IDE 提示?谢谢

以上是关于PHP 接口有属性吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以反序列化为 protobuf-net 中接口的只读属性吗?

TypeScript 接口可以限制其实现类的属性吗?

在 PHP 中使用静态方法和属性会占用更少的内存吗?

Java的类与接口有什么作用?支持多继承吗?

您可以在 PHP 中动态创建实例属性吗?

C# 类可以从其接口继承属性吗?