为什么PHP traits不具有静态抽象方法?
通过
PHP v5.3中的静态绑定,可以在接口中有效地声明静态方法;在PHP v5.4中具有特征,方法可以是静态还是抽象,但不能同时使用.这似乎是不合逻辑的和不一致的.
特别地,假设一个特征提供所有实现的接口,除了静态方法;除非该特性中声明了该方法,否则静态分析器将在特征内部引用任何引用.但是,在特征中提供具体的实现不再强制执行/使用类来提供自己的实现 – 这是危险的;抽象静态是理想的,但不允许. 这个矛盾的解释是什么?你会如何建议解决这个问题? interface MyInterface { public static function getSetting(); public function doSomethingWithSetting(); } trait MyTrait { public abstract static function getSetting(); // I want this... public function doSomethingWithSetting() { $setting = static::getSetting(); // ...so that I can do this /* ... */ } } class MyClass implements MyInterface { use MyTrait; public static function getSetting() { return /* ... */ } }
TL; DR:您可以在特征上定义抽象静态,但内部认为这是不好的做法,可能会在将来删除它.
没有多少咖啡因,但我会给它一个裂缝. 严格来说,抽象意味着子类必须实现,静态意味着这个特定类的代码.总而言之,抽象静态意味着“子类必须为此特定类实现代码”.完全正交的概念. 但是,PHP 5.3支持静态继承感谢LSB.所以我们实际上打开了这个定义:自己采用以前的静态定义,而static变为“这个特定类或其任何子类的代码”.抽象静态的新定义是“子类必须为此特定类或其任何子类实现代码”.这可能导致一些人在严格意义上认为静态混淆.参见例如bug #53081. 什么使特质如此特别的引出这个警告?那么看看实施通知的engine code: if (ptr->flags & ZEND_ACC_STATIC && (!scope || !(scope->ce_flags & ZEND_ACC_INTERFACE))) { zend_error(error_type,"Static function %s%s%s() cannot be abstract",scope ? ZSTR_VAL(scope->name) : "",scope ? "::" : "",ptr->fname); } 该代码表示??允许抽象静态的唯一位置在接口内.特征不是唯一的,它是抽象静态的定义所独有的.为什么?那么我们的定义有一个小小的角落:
使用此代码: abstract class Foo { abstract public static function get(); } 那个定义意味着我应该能够调用Foo :: get.毕竟Foo是一个类(看到那个关键字“class”),而在严格的定义中,get就是要在这个类Foo中实现的.但是很明显,没有任何意义,因为我们回到了严格静态的正交性. 如果您尝试使用PHP,您可以获得唯一的理由响应:
所以因为PHP添加静态继承,它必须处理这些角落的情况.这是特征的本质.一些其他语言(C#,Java等)没有这个问题,因为它们采用严格的定义,根本不允许抽象静态.为了摆脱这种情况,简化引擎,我们可能会在将来强制执行这个“仅在接口中的抽象静态”规则.因此,E_STRICT. 我会使用服务代理来解决问题:
trait MyTrait { public function doSomethingWithSetting() { $service = new MyService($this); return $service->doSomethingWithSetting(); } } class MyService { public function __construct(MyInterface $object) { $this->object = $object; } public function doSomethingWithSetting() { $setting = $this->object->getSetting(); return $setting; } } 感觉有点Rube Goldberg.可能会看静态的动机,并考虑重构它们. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |