所以,我有以下课程:
class db {
function __construct() { ... }
}
我可以这样实例化:$db = new db();
我有另一个类 - 构成我的应用程序主干的主类。我们称之为主要:
class main {
public $var1;
public $db;
function __construct() {
$this->db = new db();
$this->start();
}
function start() {
$child = new child();
}
}
初始化数据库对象后,我想调用我的子类(这是main的扩展,如下所示:
class child extends main {
function __construct(){
echo parent::$var1; // Prints whatever is in $var1
}
function doSomething(){
parent::$db->runQuery(); // Doesn't work
}
}
然而,这不起作用。显然,我可以简单地在我的主类之外声明我的$db
对象,并使用global $db;
在孩子身上再次重新选择它,但我不愿意(因为这意味着每一行都有这条线)将使用数据库对象的单个函数。)
如何让我的$db
对象可用于子类?
答案 0 :(得分:1)
子对象从父级继承所有属性和方法。这将有效:
class child extends main {
function __construct(){
parent::__construct();
echo $this->var1; // Prints whatever is in $var1
}
function doSomething(){
$this->db->runQuery(); // Doesn't work
}
}
答案 1 :(得分:1)
截至目前,您可以从有权访问该类实例的任何位置访问$db
,因为您将其定义为public
。它也会继承到所有子类,这意味着您可以在此使用$this
而不是parent
。您也可以将其声明为protected
,这对于封装来说可能更好。
直接引用父变量通常是一个坏主意(并且无论如何都不可能在PHP中),因为OO的一个主要特性是继承,并且必要时可以覆盖父变量。
您绝对应该阅读面向对象编程中的继承和封装。
答案 2 :(得分:1)
由于'child'扩展'main',它现在拥有'main'成员。因此,您可以使用箭头操作符访问属性作为本地属性,正如Jonah Bron所说。
class child extends main {
function __construct(){
echo $this->$var1;
}
function doSomething(){
$this->db->runQuery();
}
}
一个类从其父级继承方法和属性,但父级的构造函数不会自动运行。您正在寻找访问'db'对象但尚未实例化的对象。你可以使用parent::__construct()
手动运行父的构造函数,但要注意你的代码当前会生成一个无限的实例化循环,因为你从它的父文件中创建了一个'child'。
答案 3 :(得分:0)
从OOP的角度来看:你有一只班鸟和一只老鹰。鹰是一只鸟,但不是每只鸟都是鹰。话虽如此,如果一个人使用鸟类的物体,你只会期望一只鸟不多。所以在bird类中,对于调用类或任何子类,应该有 no 引用。而且超级班级不知道是谁叫它。它只允许知道自己,超类,实现的接口和用于实现它的练习的其他类。这些其他类不包括子类。
老鹰的用户期待一只老鹰。所以这个用户期待一只鸟的所有东西以及更多的东西。但它创造了一个鹰对象。因此,鹰的责任是确保它被正确初始化。因此,eagle构造函数首先调用父构造函数。
<?php
class Bird {
protected $var1 = '';
protected $db = null;
public function __construct() {
$this->db = new db();
}
}
class Eagle extends Bird {
public function __construct(){
parent::__construct();
echo $this->var1;
}
public function doSomething(){
$this->db->runQuery();
}
}