PHP在使用子类构造函数时保留父类属性

时间:2016-01-08 14:16:28

标签: php class oop object

我有一个父类class Database{ /** @var Object Filemaker object across the application*/ protected $fm = null; public function __construct(){ if($this->fm == null){ $this->_openConnection(); } } /** * Function to open connection to FileMaker * @return null */ private function _openConnection(){ $this->fm = new FileMaker(); } } ,如下所示

class Login extends Database{

    public function validate(){
        // $this->fm is accessed here with no constructors
        print_r($this->fm);
    }
}

我的一个孩子班是

$login = new Login();
$login->validate();

我正在创建对象,

$login = new Login();

请注意,在这个Login类中,我没有任何构造函数。所以在class PouleManipulation extends Database{ private $year; public function __construct(){ // $this->fm is only accessed if I call parent class constructor parent::__construct(); $year = '2015'; } public function processQueue(){ $this->fm->perform(); } } 行,它调用了Database类构造函数,并调用了_openConnection()。这很好

这是我的另一个孩子班:

$pm = new PouleManipulation();
$pm->processQueue();

$pm = new PouleManipulation();

现在,当我调用$this->fm时,请注意我有这个类的构造函数。如果我访问parent::__construct();,那么它会抛出一个未定义的错误。我用Google搜索,发现了,

  

在这个类构造函数中,我需要使用parent::__construct();来访问父类属性。如果我没有使用_openConnection(),那么当你在子类中使用构造函数时,父类对象是不可访问的

现在,问题出在Database类中,$ fm为null,它再次调用_openConnection()。我总共有10个类扩展了Database类,以及哪个类具有它调用_openConnection()的构造函数。

我需要在所有子类中访问$ this-> fm,第一次只调用{{1}},并且在所有类中都需要$ this-> fm。你是如何实现这一目标的?

1 个答案:

答案 0 :(得分:2)

让我们澄清一下。属性在对象级别设置。这意味着每次实例化创建对象的类时,此对象都是新的,并且具有与您实例化的其他属性不同的属性(它们可能具有相同的值,但它们存储在不同的位置,并且它们是'重新独立)。

示例:

class Database {
    public $fm = "Value";
}

class Login extends Database {}

class PouleManipulation extends Database {}


$a = new Login();
$b = new PouleManipulation();
$b->fm = "New Value";
echo $a->fm; // prints "Value"
echo $b->fm; // prints "New Value"

您正在寻找的是静态属性,它是在类级别设置的。如果通过静态方法访问它会更好。这是一个快速而肮脏的例子,但你最好使用getter和setter。

class Database {
    public static $fm = "Value";
}

class Login extends Database {}

class PouleManipulation extends Database {}

$a = new Login();
$b = new PouleManipulation();
$b::$fm = "New Value";
echo $a::$fm; // prints "New Value"
echo $b::$fm; // prints "New Value"

修改 我使用你提供的代码来解释如何实现你想要的,但我想强调一下Ryan Vincent在评论中所写的内容:Login类应该使用(不扩展)Database