PHP抽象静态类方法的替代模型

时间:2013-02-15 12:20:36

标签: php oop abstract-class

好的,所以我在这里已经阅读了很多posts,但我认为这是一个特定的新问题。

我希望我们这里的许多人错误地称之为“抽象静态方法”的功能。那就是:我想要一个坚持扩展它的类的类实现某些静态方法

似乎有两条道路围绕着讨论不多的问题,即不允许抽象静态,但两者似乎都不够优雅。

问题

以下内容会产生错误:“PHP严格标准:静态函数A :: fn()不应该是抽象的”。

<?php
abstract class A
{
     abstract static public function fn();
}

class B extends A
{
    static public function fn()
    {
         // does something on class vars etc.
    }
}

解决方案1:使用接口

<?php
interface iA {
    static function fn();
}


abstract class A implements iA 
{
} // obviously this would have other stuff in it in reality

class B extends A
{
    static public function fn()
    {
         // does something on class vars etc.
    }
}

这个问题是接口假设(指示)所有方法都是公共的。因此,虽然这实现了坚持抽象类的子类具有某些静态方法的目标,但它只能用于公共方法;仍然无法确保A的子类实现受保护的静态方法。

当方法完全依赖于静态数据但不应该从“外部”调用时,受保护的静态方法很有用。

解决方案2:例外

abstract class A
{
     static public function fn()
     {  
         throw new Exception(get_called_class() . " must implement fn()");
     }

}

class B extends A
{
    static public function fn()
    {
         // does something on class vars etc.
    }
}

如果调用fn(),这在运行时有效。但是必须在运行时处理编码语法错误没有用。虽然这可能是一种方法的破解,但每种方法的代码都要多得多。

这个设计有什么问题,语言是否正确禁止它?奇怪的是,有多种方法可以坚持子类提供大多数类型的方法,但不提供静态方法。

2 个答案:

答案 0 :(得分:2)

这是因为静态方法属于定义它们的A::fn()B::fn()是两种不同的方法,无论继承树如何。因此,将A::fn()定义为abstract

是没有意义的

也许你的方法不应该是抽象的?如果你想使用任何类型的多态,那么应该有相关的对象。

答案 1 :(得分:0)

我可能完全错了,但我使用

没问题
abstract class A
{
     abstract static public function fn();
}

class B extends A
{
    static public function fn()
    {
         print 1;
    }
}

B::fn();

它产生1作为输出。我在here中运行了您的代码。您使用的是什么版本的PHP?