不继承父类方法和属性的子类


OO PHP - child class not inheriting parent methods and properties

我有一个非常简单的OO类结构,无法理解为什么子类不继承父类的属性和方法。

这是我设置的一个基本示例:

//Main class:
class Main{
    //construct
    public function Main(){
        //get data from model
        $data = $model->getData();
        //Get the view
        $view = new View();
        //Init view
        $view->init( $data );
        //Get html
        $view->getHTML();
    }
}

//Parent View class
class View{
    public $data, $img_cache; 
    public function init( $data ){       
        $this->data = $data;
        $this->img_cache = new ImageCache();
    }
    public function getHTML(){
        //At this point all data is intact (data, img_cache)
        $view = new ChildView();
        //After getting reference to child class all data is null
        //I expected it to return a reference to the child class and be able to 
        //call the parent methods and properties using this object. 
        return $view->html();
    }
}

//Child View Class
class ChildView{
    public function html(){
        //I get a fatal error here: calling img_cache on a non-object.
        //But it should have inherited this from the parent class surely?
        return '<img src="'.$this->img_cache->thumb($this->data['img-src']).'"/>';       
    }
}

所以我希望子类继承父类的属性和方法。然后,当我得到对子类的引用时,它应该能够使用img_cache对象。但是我在这里得到一个致命的错误:Call to a member function thumb() on a non-object .

我哪里错了?

您需要指定继承与扩展基类http://php.net/manual/en/keyword.extends.php

为您的子类

尝试此操作
//Child View Class
class ChildView extends View{
    public function html(){
        //I get a fatal error here: calling img_cache on a non-object.
        //But it should have inherited this from the parent class surely?
        return '<img src="'.$this->img_cache->thumb($this->data['img-src']).'"/>';       
    }
}

也正如@ferdynator所说,您正在实例化父类,而不是子类,因此您的Main类也需要更改为实例化ChildView,而不是父View

//Main class:
class Main{
    //construct
    public function Main(){
        //get data from model
        $data = $model->getData();
        //Get the view
        $view = new ChildView();
        //Init view
        $view->init( $data );
        //Get html
        $view->getHTML();
    }
}

不能通过实例化子类来创建子类。你把extends作为超类。

然后你可以在一个抽象的超类中创建一个抽象方法(或者如果你不想让它是抽象的,可以创建一个默认实现),并通过声明一个同名的方法在extends超类的子类中实现它。

//Main class:
class Main{
    //construct
    public function Main(){
        //get data from model
        $data = $model->getData();
        //Get the view
        $view = new ChildView(); // <--- changed
        //Init view
        $view->init( $data );
        //Get html
        $view->getHTML();
    }
}

//Parent View class
abstract class View{ // <--- changed
    public $data, $img_cache; 
    public function init( $data ){       
        $this->data = $data;
        $this->img_cache = new ImageCache();
    }
    public abstract function getHTML(); // <--- changed
}

//Child View Class
class ChildView extends View{ // <--- changed
    public function getHTML(){ // <--- changed
        //I get a fatal error here: calling img_cache on a non-object.
        //But it should have inherited this from the parent class surely?
        return '<img src="'.$this->img_cache->thumb($this->data['img-src']).'"/>';       
    }
}
简单地说,子类和父类具有相同的实例。它们只是包含来自不同类的代码,但它们仍然是相同的对象。只有相同的对象可以获得相同的属性。

顺便说一句,使用__construct的构造函数(public function __construct代替public function Main)。使用类名作为构造函数名是非常过时的,可能会被弃用(不确定它是否已经被弃用)。