如何防止在PHP的子实例中使用公共父方法?

Fir*_*rze 6 php inheritance visibility class parent-child

假设我有一个名为parent和child的类,然后将在名为caller.php的PHP文件中使用该类

class Child extends Parent {

}

class Parent {

    public function parentMethod(){

    }
}
Run Code Online (Sandbox Code Playgroud)

caller.php

预防:

$child = new Child();
$child->parentMethod();
Run Code Online (Sandbox Code Playgroud)

允许:

$parent = new Parent();
$parent->parentMethod();
Run Code Online (Sandbox Code Playgroud)

我想防止像这样调用parentMethod。但是,如果我创建了Parent对象,我希望能够调用parentMethod。我可以使用某种方法来隐藏此方法以使其在Child类中不公开,但仍允许父对象公开调用此方法吗?

到目前为止,我想出的唯一解决方案是使这些方法受保护,然后创建另一个类,该类将扩展父类,然后为其需要的每个函数提供公共方法,但这听起来并不很聪明。

Alm*_* Do 7

实际上,您应该问自己:为什么需要这种限制?您将方法定义为public-因此,您告诉PHP在任何地方都应该可见。因此,为防止子调用,您应该使用private可见性定义。

有一种方法可以检查是否从父类进行了调用,例如:

class ChildClass extends ParentClass {}

class ParentClass 
{

    public function parentMethod()
    {
       if(get_class($this) != __CLASS__)
       {
          throw new LogicException("Somehow due to business logic you're not allowed to call this from childs");
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我不建议这样做。原因如下:

  • 可读性。您的方法只是普通的公共方法。期待它是不可能的,您应该使用它或不使用它。因此,要维护此类代码,您需要检查代码中的限制。现在,假设您有大约50种这样的方法。还有几十个这样的课程。
  • 可能违反了得墨Law耳定律。使用此类限制时,为什么父类应该知道它是孩子?
  • 最后,这只是意外行为。根据定义,任何人都会看到您正在一个班级扩展到另一个班级。因此,根据定义,所有具有适当可见性的继承方法都必须被继承。而你的逻辑改变了这一点。

您可能会考虑组成,而不是继承。那可能是实现您的逻辑的正确方法(但是,由于我不了解整个背景,我不能肯定地说出来)