我需要在PHP中有一个类构造函数调用父类的父类的(祖父母?)构造函数,而不调用父类构造函数。

// main class that everything inherits
class Grandpa 
{
    public function __construct()
    {

    }

}

class Papa extends Grandpa
{
    public function __construct()
    {
        // call Grandpa's constructor
        parent::__construct();
    }
}

class Kiddo extends Papa
{
    public function __construct()
    {
        // THIS IS WHERE I NEED TO CALL GRANDPA'S
        // CONSTRUCTOR AND NOT PAPA'S
    }
}

我知道这是一件很奇怪的事情,我正试图找到一种不难闻的方法,但尽管如此,我很好奇这是否可能。


当前回答

关于php的有趣细节:扩展类可以在静态事务中使用父类的非静态函数。在外面你会得到一个严格的错误。

error_reporting(E_ALL);

class GrandPa
{
    public function __construct()
    {
        print("construct grandpa<br/>");
        $this->grandPaFkt();
    }

    protected function grandPaFkt(){
        print(">>do Grandpa<br/>");
    }
}

class Pa extends GrandPa
{
    public function __construct()
    {   parent::__construct();
        print("construct Pa <br/>");
    }

    public function paFkt(){
        print(">>do Pa <br>");
    }
}

class Child extends Pa
{
    public function __construct()
    {
        GrandPa::__construct();
        Pa::paFkt();//allright
        //parent::__construct();//whatever you want
        print("construct Child<br/>");
    }

}

$test=new Child();
$test::paFkt();//strict error 

因此在扩展类(Child)中可以使用

parent::paFkt(); 

or

Pa::paFkt();

访问父(或祖父)(非私有)函数。

类定义之外

$test::paFkt();

将trostrict错误(非静态函数)。

其他回答

从PHP 7你可以使用

家长:家长:__construct ();

class Grandpa 
{
    public function __construct()
    {}
}

class Papa extends Grandpa
{
    public function __construct()
    {
        //call Grandpa's constructor
        parent::__construct();
    }
}

class Kiddo extends Papa
{
    public function __construct()
    {
        //this is not a bug, it works that way in php
        Grandpa::__construct();
    }
}

好吧,还有一个丑陋的解决方案:

在Papa中创建一个函数:

protected function call2Granpa() {
     return parent::__construct();
}

然后在Kiddo中使用:

父:call2Granpa ();//而不是调用Papa中的构造函数。

我认为这可行……我还没有测试过,所以我不确定是否 对象被正确创建。

我使用了这种方法,但是使用了非构造函数。

    class Grandpa 
{
    public function __construct()
    {
        echo"Hello Kiddo";
    }    
}

class Papa extends Grandpa
{
    public function __construct()
    {            
    }
    public function CallGranddad()
    {
        parent::__construct();
    }
}

class Kiddo extends Papa
{
    public function __construct()
    {

    }
    public function needSomethingFromGrandDad
    {
       parent::CallGranddad();
    }
}

你必须使用外公::__construct(),没有其他的快捷方式。此外,这也破坏了Papa类的封装——当读取或处理Papa时,应该可以安全地假设__construct()方法将在构造过程中被调用,但Kiddo类不会这样做。