【问题标题】:PHP Inheritance: If A then Must Set BPHP 继承:如果 A 则必须设置 B
【发布时间】:2011-04-12 12:01:19
【问题描述】:

所以,我尝试谷歌这个但不知道这种情况叫什么......

我正在第一次使用类继承,其中一个父类定义一组方法,然后其他几个类扩展该父类。

我想知道的是,有没有可能做这样的事情:

class foo {
  private bar = false;
  private baz = NULL;
}

现在假设我有:

class foobar extends foo { }

我希望能够在“foo”中有一个条件,即如果任何类扩展“foo”并设置“bar = true”,则必须设置“baz”(即不为空),否则抛出异常。

这样的事情可能吗?

【问题讨论】:

  • Waitasecond... 如果变量声明为private,则继承的类无论如何都无法访问它们。那么这有什么意义呢?
  • 如果您在父级中定义 getter 和 setter,它们确实可以访问,或者您可以将它们更改为受保护。这样做的目的是为了让一些东西万无一失。基本上我有一个父母有很多有用的“幕后”东西,我希望使用代码的人扩展它而不是使用它或直接编辑它,我正在尝试创建一个场景如果他们想要启用某个功能(bar = true),那么如果他们不包含所需的信息(baz != null),他们会收到一个非常具体的错误消息。

标签: php class inheritance


【解决方案1】:

这似乎可以通过使用您在foo 中定义的magic setter function 来实现,但有一个严重的警告。魔术 getter 和 setter 仅在您访问不可访问的属性时触发。

在类内部操作时,所有属性,无论是声明为私有、公共还是受保护的,通常都是可访问的,因此魔法 getter 和 setter 函数不会触发。只有一个例外:在祖先类中声明为 private 的属性。这些将对后代类隐藏(无法访问),并且会触发魔法函数。

这意味着您需要在foo 中声明barbaz。如果您在foobar 中声明它们是行不通的,因为它们将变得可访问。

考虑到这一点,以下将按您的意愿工作:

class foo {
  private $bar = false;
  private $baz = NULL;

  public function __set($name, $value)
   {
     if ($name == "bar") 
      { if ($value == true)
         {
           if ($this->baz == null) 
            throw new Exception();
         }
      }
   } 
}

class foobar extends foo {

     function test()
      {
       $this->bar = "TEST";   
      }

 }


 $foobar = new foobar();
 $foobar->test();  // Will throw an exception

如果您想从foobar 中读取barbaz,您还需要定义一个魔术getter 函数。

【讨论】:

  • @Andrew 不客气。我自己有点惊讶这是可能的 :) 必须在祖先中声明属性私有才能让 getter 和 setter 着火似乎有些武断,但我对其进行了测试,它似乎工作正常。
【解决方案2】:

只需在第二个类中运行一个构造函数。

class foo {
  private bar = false;
  private baz = NULL;
  public function __construct() {
    if ($this->bar && is_null($this->baz)) // throw exception
  }
}
class foobar extends foo {
  public function __construct($baz) {
    $this->baz = $baz;
    $this->bar = true;
    parent::__construct(); // Now run the parent's constructor
  }
}

许多不同的方法来做到这一点......

【讨论】:

  • 是的,但我想这样做的真正原因是我认为 可能不是编写“foobar”类的人。因此,如果有人尝试使用父级的某个功能(bar = true),那么他们还必须提供一些信息(baz != null)。由于我关心的是捕获父类的不完整扩展,因此我不希望实现依赖于子类中的任何代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-11
  • 2015-11-18
  • 2014-08-14
  • 1970-01-01
  • 2015-05-01
相关资源
最近更新 更多