2011-03-02 118 views
3

不知何故,我的思想远离当前的问题,我犯了一个可怕的错误。 我在一个刚刚初始化类属性的方法中调用了父构造函数..或者我..父构造函数工作是设置ID值。那么PHP允许我这样做。但是,这不正确?它看起来像我可以用同样的方式调用类自己的构造函数。难道不应该只允许构造函数在创建类的实例时被调用...并且它们仅在创建实例时才被调用..调用方法内的构造函数

<?php 

    class A { 

     public function __construct() { 
      echo "Test<br />"; 
     } 

    } 

    class B extends A { 

     public function test() { 
      parent::__construct(); 
     } 

    } 

    $b = new B(); 
    $b->test(); 

    // OUTPUT: 
    // Test 
    // Test 

?> 

编辑:所以结论是,PHP允许你调用方法内的构造函数,但它实际上什么都不做。另一个“TEST”字符串来自基类的构造函数。

+1

我敢肯定,会导致内爆(“,”,$ theInterwebs) – Detect 2011-03-02 21:49:15

+0

道德上,这是绝对错误的。只是不要这样做。 – Detect 2011-03-02 21:49:56

+0

当你急着做东西,然后意识到发生的事情非常奇怪,这很有趣。 :) – PPPHP 2011-03-02 22:03:37

回答

3

一个词完全描述了情况。

覆盖

什么情况是,当父母有这样的方法为__construct和子类中没有该方法,当方法被调用子类中调用的父母方法。

例如:

class Parent 
{ 
    public function start(){} 
} 
class Child extends Parent 
{ 

} 

如果我叫子类中所涉及的起动方法,它执行Parent::Start(),但如果儿童类有一个叫做Start()方法是一个将被称为其重写的父母版本。

每个类都有一个构造函数方法,php执行它来将该类编译成一个对象,现在如果在类中有一个名为__construct()的方法,PHP调用编译该类的内部构造,然后调用您的覆盖构造函数。

如果你没有在子类PHP一个__construct方法执行父__construct

这就是为什么在你的对象初始化得到 X Test

您应该使用parent:__cosntruct()的唯一时间是如果您的Child类需要用户定义的构造函数,则显式调用父构造来准备父对象。

例如:

class Parent 
{ 
    public function __construct() 
    { 
     //Do work on Parent Class 
    } 
} 

class Child extends Parent 
{ 
    public function __construct() 
    { 
     //Do Work on Child Class 

     parent::__construct(); 
    } 
} 

你应该只调用过一个孩子的构造中和父类的构造不是一个孩子方法的原因是,构造函数应该永远只被调用一次,这样一来强制执行。

+0

哦,是的,这是正确的。 – PPPHP 2011-03-02 22:10:31

+1

如果PHP会以某种方式显示错误或其他东西,它仍然会很好。 – PPPHP 2011-03-02 22:11:42

+0

你是绝对正确的。那么现在我尽量不要失去焦点。 :)不知何故,我在这个层面上,即使是像这些最简单最基本的东西,我也会质疑。不知何故,我需要有人向我说出什么是对的,什么是错的。 – PPPHP 2011-03-02 22:27:12

1

您不会在任意时间调用父构造函数。您只能从子构造函数调用父构造函数,即在构造对象时。

如果php另有说明,那么这仅仅是语言中如何实现类的一种人造物,而不应该被认为是它永远是件好事。

0

这不是一个好习惯,而良好的OOP语言通常不会让你这样做。如果你确切地知道你在做什么,那完全没问题。 (你可以记录下来,所以其他使用该代码的程序员理解你的概念)。

0

我会建议使用“init”方法来处理这种行为。下面是一个例子:

class A { 
    public function __construct() { 
     $this->init(); 
    } 
    protected function init() { 
     echo "Test<br />"; 
    } 
} 

class B extends A { 
    public function __construct() { 
     // suppress parent constructor 
    } 
    public function test() { 
     $this->init(); 
    } 
}