6

好的,所以我在这里阅读了很多关于此的帖子,但我认为这是一个具体的新问题。

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

似乎有两条路可以解决很多讨论过的不允许抽象静态的问题,但似乎都不优雅。

问题

以下会生成错误:“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(),这在运行时有效。但是在运行时必须处理编码语法错误是没有用的。虽然这可能是一种方法的破解,但每种方法的代码要多得多。

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

4

2 回答 2

2

这是因为静态方法属于定义它们的类。A::fn() 并且B::fn()是两种不同的方法,与继承树无关。所以定义A::fn()为没有什么意义abstract

也许您所讨论的方法根本不应该是抽象的?如果您想使用任何类型的多态性,则应该涉及到对象。

于 2013-02-15T12:59:17.673 回答
0

我可能完全错了,但我使用没有问题

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

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

B::fn();

它产生 1 作为输出。我在这里运行了你的代码。你用什么版本的php?

于 2013-02-15T12:46:01.957 回答