关于何时从php中的子类实例化父类的困惑

时间:2014-02-05 21:28:04

标签: php oop

我正在创建一个网站,但为了提高我的编码技能,我正在努力利用OOP的力量。

我正在使用类来验证表单输入,所以我认为我有一个'父级'验证类,然后是每个提交的表单的子类(即登录类,注册类等),它们会处理正确的值进入数据库等。

我见过的代码中父代是从子构造函数构造的。但是,我没有这样做,但我的班级似乎仍在工作?

有人可以向我解释为什么我们从孩子那里调用父构造函数吗? 另外,我的代码是否正常工作,因为我的父母有'公共'功能(方法)? (这可能是个问题吗?)

我的代码(为清晰起见,删节版)如下:

class Validation_Class
{
 public function __construct()
{
 // constructor not needed
 }

 public function is_genuine_email_address($email) {
     // code to validate email are genuine here...
     }

 }

我的孩子班看起来像......

class Login_Class extends Validation_Class
{

public function __construct()
{
    // I don't call parent::__construct() from here
    // should I be doing?
    // I can still access parent methods with $this->is_genuine_email_address
    }

 }

我的Validation_Class中的所有函数(方法)都是'public',当我实例化我的子类时,我可以调用任何Validation Class方法:

$className = "Login_Class";
$thisClass = new $className();

3 个答案:

答案 0 :(得分:4)

从架构的角度来看,这没有多大意义。因为使用OO继承不仅仅是在代码中扩展一个类,而且还是以一种有意义的方式设计和构造类层次结构。

从逻辑结构标记点我不会想象一个Login类要从验证类继承。相反,我可能有一个验证类对象作为Login类的成员,并使用其函数来执行验证。

从继承的角度来看,永远记住我们应该努力拥有代表'对象'而不是'动作'的类。当然,我们可以使用登录和验证操作的类,但操作很少以父子方式继承。他们更好地相互补充。

调用父类,无论是构造函数还是标准方法都不是必需的。如果您正在父项中指定的操作的一部分,则需要它,并且将在子项中定义更细粒度的操作。

拇指的规则是,当你遍历一个继承的类链时,它变得越来越通用,当你遍历时,它变得越来越专业化。

答案 1 :(得分:4)

调用父构造函数

并不是一件好事
class Parent {
  //maybe just holding some constants
  public $database = 'mydatabase';
}

class Child extends Parent {
   public function myFunction() {
     if ($this->database == 'myDatabase') {
       // you can access the parents data without calling a constructor
     }
  }
}

很好。但是如果你想从父母为了正常工作而必须做的事情中受益,可能需要调用父__construct - 比如

class Parent {
  public $database = null;
  public function __construct() {
    // example -> login to database
  }
}

class Child extends Parent {
  public function __construct() {
    parent::__construct();
    // .. further code
  }

  public function myFunction() {
     // do something, like executing a query
     $this->database->executeQuery($SQL);
  }
}

在PHP“OOP”中,它不是你在其他语言中看到的真正的OOP,构造函数只是实例化生成的对象的简写。如果我们一遍又一遍地打电话

,那将是一场地狱
$object = new MyClass();
$object->instantiate()

因此调用__constructnew ClassName()会更容易。但是,类继承者并不是绝对需要正常工作,他们在类层次结构中调用构造函数。当然,除非其中一个班级父母需要某些初始化才能让继任者正常工作。

答案 2 :(得分:0)

使用策略模式进行验证不是使用继承,而是可用的流行模式之一。这使代码更加模块化和可扩展,

Validating Incoming Data with the Strategy Design Pattern