【问题标题】:Is it proper for a parent class to reference a property that exists only in the child?父类引用仅存在于子类中的属性是否合适?
【发布时间】:2009-10-26 19:37:54
【问题描述】:

在我的团队目前正在进行的项目中,我们正在修改一个商业 PHP 应用程序。该应用程序到处都是代码,其中父类检查并使用父类中不存在的属性,如下所示:

class A 
{
    function doSomething()
    {
        if (property_exists($this, 'some_property'))
        {
            $this->some_property = $_REQUEST['val'];
        }
    }

}

class B extends A
{
    protected $some_property;

    function doSomething()
    {
        parent::doSomething();
    }
}

我们觉得不得不修改这段代码有点肮脏;这是正确的设计吗?有哪些方法(除了显而易见的)可以避免这种情况?

【问题讨论】:

    标签: php oop


    【解决方案1】:

    您可以将abstracting 视为父类。所以子项必须有的方法在父项中声明,但没有实现。

    【讨论】:

    • 同意。不幸的是,在这种情况下,父类被认为是“核心代码”,我们不允许接触。
    • 我同意这个答案。你发现的是一种你会不止一次遇到的技术。它可能非常有用。但是应该使用抽象基类,因为该类显然不完整,应该使用多态来完成。
    • 根据团队成员的评论,s/不允许/强烈建议不要/
    • @Chris Miller:好吧,如果您不能抽象父级,那么您可以在所有子级上实现一个接口。它不是那么好,因为您必须记住在每个类定义中都这样做(这并不是接口的真正含义),但总比没有好。
    • 一种可能让您感觉更舒服的变体是使用抽象方法,例如getThatProperty()。或者在基类中有一个默认实现,让子类决定是否覆盖它。
    【解决方案2】:

    依赖必须存在于子类中的方法并不肮脏,只要您可以将它们声明为抽象即可。

    但是,依赖和操作类之外的属性并不是一个好习惯。最好使用抽象设置器,如下所示:

    abstract class A 
    {
        abstract protected function setSomeProperty($data);
    
        public function doSomething()
        {
            $this->setSomeProperty($_REQUEST['val']);
        }
    }
    
    class B extends A
    {
        private $some_property;
    
        public function doSomething()
        {
            parent::doSomething();
        }
    
        protected function setSomeProperty($data)
        {
            $this->some_property = $data;
        }
    }
    

    更多信息在这里:PHP Class Abstraction

    然而,既然你说你不允许修改父类,我建议创建一个子类,作为父类“期望”的Adapter,以及您能够“正确”设计的类。

    【讨论】:

    • 感谢大家提供非常好的答案。我认为由于技术限制不足 (>.
    【解决方案3】:

    您可以在父类中创建一个虚拟方法挂钩,以后可以被子类覆盖。

    【讨论】:

      【解决方案4】:

      我认为创建一个子类更简洁,其中所有成员都有函数doSomething()。在这种情况下,您不会在父类中创建不起作用的函数(最终会被破解),但仍然具有一般的“超级函数”。

      class A 
      {
      
      
      }
      class C extends A {
      
          protected $some_property;
      
          function doSomething()
          {
              $this->some_property = $_REQUEST['val'];
          }
      }
      
      class B extends C
      {
          protected $some_property;
      
          function doSomething()
          {
              parent::doSomething();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-05-14
        • 2020-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-17
        • 2015-03-14
        • 2013-03-07
        相关资源
        最近更新 更多