PHP中的几乎最终方法?

FtD*_*Xw6 5 php inheritance overriding final

我在继承链中有两个抽象类,最终将成为通用库:

abstract class Foo {
    public function baz() {
        echo 'Foo::baz()';
    }

    // other methods here
}

abstract class Bar extends Foo {
    public function baz() {
        echo 'Bar::baz()';
    }
}
Run Code Online (Sandbox Code Playgroud)

这两个类是由开发人员扩展的,我的问题是我想这样做,以便不能baz()覆盖该方法的任何实现(因为它们包含严格的RFC兼容代码).制作Bar::baz() final没问题; 但是,如果我做Foo::baz() final,那么Bar它本身显然也无法覆盖它.

PHP 5.4 trait可能会提供一个实用的解决方案,但我不能放弃对PHP <5.4的支持.我的最后一招是让它保持原样,并使用文档警告开发人员不要覆盖这种方法,但我想找到更具体的东西,如果可能的话.

是否有任何其他设计可以用来强制执行这两个方法不应该被覆盖,同时保持代码DRY(例如不删除继承和复制所有代码)?

nai*_*rbv 1

这似乎适用于“优先组合而不是继承”的想法。它有点重复,但它不涉及重复的实现,并为您提供了您想要的功能。

interface Bazr {
    public function baz();

    public function myOtherMethod1();
    public function myOtherMethod2();
}

public class Foo implements Bazr {
  public final function baz() {} 
  public function myOtherMethod1() {/* default implementation of some method */}
  public function myOtherMethod2() {/* yeah */}
}

public class Bar implements Bazr {
  private parentBazr = null;
  public function __construct() {
    $this->parentBazr = new Foo();
  }

  public final function baz() {}
  public function myOtherMethod1() {
    $this->parentBazr->myOtherMethod1();
  }
  public function myOtherMethod2() {
    $this->parentBazr->myOtherMethod1();
  }
}
Run Code Online (Sandbox Code Playgroud)

Foo 和 Bar 都可以扩展,Bar“组合”了 Foo 的功能,而 baz 在 Foo 和 Bar 中都是最终的。我不确定您是否喜欢包含或省略接口... PHP 没有类型化变量,因此除了强制执行与两个实现类的约定之外,可能没有必要。定义接口的缺点是其他人可以实现该接口(尽管特征也是如此)。

抱歉,如果我混合了 java/php 语法,我想我遗漏了一些“$”。