Php 如何强制实现受保护的静态函数

Php 如何强制实现受保护的静态函数,php,static,abstract,protected,Php,Static,Abstract,Protected,我试图编写一个抽象类(或接口),强制扩展类实现一个受保护的静态函数。 但对于抽象类或接口,这是不可能的 错误: 静态函数不应该是抽象的 必须省略接口成员的访问类型 有没有办法做到这一点 更新 其目的基本上是静态调用公共函数。这样,类就不需要实例化。 也不必使_doSpecificStuff()可从类外部代码调用 abstract class Foo { public static function doStuff() { [generic code]

我试图编写一个抽象类(或接口),强制扩展类实现一个受保护的静态函数。 但对于抽象类或接口,这是不可能的

错误:

  • 静态函数不应该是抽象的
  • 必须省略接口成员的访问类型
有没有办法做到这一点

更新

其目的基本上是静态调用公共函数。这样,类就不需要实例化。 也不必使_doSpecificStuff()可从类外部代码调用

abstract class Foo
{
    public static function doStuff()
    {
        [generic code] 

        static::_doSpecificStuff();
    }

    // sth like that would be nice to have:
    abstract static protected function _doSpecificStuff();
}

从理论和实践的角度来看,没有必要声明静态方法抽象

抽象方法用于让子类填充空白。这通常是因为父类(原始抽象类)执行一些泛型操作,但可以/必须适应某些特定情况,因此可以强制子类在其他泛型算法中仅实现此特定变量部分。抽象方法应该是较大算法中的一个空白点

父方法将调用其抽象方法的实现,而不知道或关心是谁实现了它们或它们是如何实现的:

abstract class Foo {

    public function someAlgo() {
        $foo = $this->doSomethingSpecific();
        ...
    }

    abstract protected function doSomethingSpecific();

}

<代码> fo不关心谁或什么填充了空白<代码>特定细节,它只依赖于它在那里和它的签名,<代码>抽象>代码>强制执行。实现此方法或其实现方式的特定对象是可变的。这很重要,也是问题的核心

在这种情况下,声明静态方法抽象是非常无用的。任何静态方法都可以作为非静态方法来实现,因此在这里没有任何用处。如果类本身应该调用抽象方法作为上述更大的泛型算法的一部分,那么就不需要静态方法

因此,静态方法剩下的唯一场景是可从任何地方调用的
公共静态
方法:

abstract class Foo {

    abstract public static function bar();

}

class Baz extends Foo {

    public static function bar() { ... }

}

Baz::bar();
问题是,因为
抽象类Foo
本身并没有调用这个函数,但是这个函数只是从外部代码调用的,所以你说的不是填空方法,而是一个接口。因此,您应该改用
接口

但即使这样,由于您必须在源代码中键入特定的类名(硬编码),因此接口也没有什么意义

声明接口或抽象方法签名的要点是,您希望修复方法签名,以便任何代码都可以调用该特定方法,而不必关心它调用它的特定对象。但是,由于必须硬编码类名,因此在调用它的对象中没有变化。如果键入
Baz::bar()
,您就可以确切地知道要在哪个类上调用哪个方法。因此,抽象接口/签名没有什么意义


比较:

interface FooInterface {

    public function bar();

}

function baz(FooInterface $foo) {
    $foo->bar();
}
由于接口声明,函数
baz
可以依赖其参数具有
bar()
方法。实现该方法的特定对象是不相关的,并且会有所不同

abstract class Foo {

    public function someAlgo() {
        $foo = $this->doSomethingSpecific();
        ...
    }

    abstract protected function doSomethingSpecific();

}
abstract class Foo {

    abstract public static function bar();

}

class Baz extends Foo {

    public static function bar() { ... }

}

Baz::bar();
Foo
可以依赖于它具有
doSomethingsSpecific
方法。实现该方法的特定对象是不相关的,并且会有所不同

abstract class Foo {

    public function someAlgo() {
        $foo = $this->doSomethingSpecific();
        ...
    }

    abstract protected function doSomethingSpecific();

}
abstract class Foo {

    abstract public static function bar();

}

class Baz extends Foo {

    public static function bar() { ... }

}

Baz::bar();

你到底在依赖什么或抽象什么?您可以非常肯定
Baz
每次都会有方法
bar()
,因为您只在同一个硬编码类上调用它。这里没有什么是可变的。

谢谢您的详细回答!由于注释中的代码格式不起作用,我更新了这个问题。“这样类就不需要实例化。”-这基本上是“面向类的编程”,基本上忽略了OOP的要点。在最近添加了后期静态绑定之前,它毫无意义,即使是现在,“面向类的编程”也缺少类的意义。看,你说得对。但是静态方法的思想是独立于实例进行操作。当然,解决方案是实例化该类。但是从程序员的角度来看,没有必要实例化它,因为该方法可以独立于实际实例工作。换句话说:我对可能性而不是范例感兴趣。正如你在我链接的文章中所读到的,使用静态方法/类是一个相当有争议的问题。我可以大致了解您的用例,但OOP应该用于对象,不鼓励不使用对象,这就是为什么您会收到严格通知的原因。你仍然可以做你想做的事情,但是PHP(和我)试图告诉你,也许你一开始就做了错事。如果你想忽略这一点,你必须禁用严格的错误报告。那么:
interface-foointeraction{static function-foommethod();}类A实现foointeraction{…}类B实现foointeraction{…}
之后:
function-callFooMethod($className){If(is_subclass_of($className,'foointeraction')){return$className::fooMethod();}
然后:
callFooMethod('A')
callFooMethod('B')
,虽然我不明白为什么还会使用这种方法,但在这种特殊情况下,您如何不使用接口来确保遵从性?