So, I have the following class:
class db {
function __construct() { ... }
}
and I can instantiate it thusly: $db = new db();
I have another class - the main class that forms the backbone of my application. Let's call it main:
class main {
public $var1;
public $db;
function __construct() {
$this->db = new db();
$this->start();
}
function start() {
$child = new child();
}
}
After the database object is initialized, I want to call my child class (which is an extension of main, like so:
class child extends main {
function __construct(){
echo parent::$var1; // Prints whatever开发者_开发知识库 is in $var1
}
function doSomething(){
parent::$db->runQuery(); // Doesn't work
}
}
However, this doesn't work. Obviously, I can simply declare my $db
object outside my main class, and use global $db;
to pick it back up again in the child, but I'd rather not (as it means having that line on every single function that would use the database object).
How can I just simply have my $db
object available to the child classes?
The child object inherits all attributes and methods from the parent. This will work:
class child extends main {
function __construct(){
parent::__construct();
echo $this->var1; // Prints whatever is in $var1
}
function doSomething(){
$this->db->runQuery(); // Doesn't work
}
}
As of right now, $db
is accessible from everywhere you have access to an instance of the class, because you defined it as public
. It is inherited to all child classes as well, which means you can use $this
instead of parent
here. You could also have it declared protected
, which is probably even better for encapsulation's sake.
Referencing the parent's variable directly is usually a bad idea (and not possible in PHP anyway), because one of the main feature of OO is inheritance and the ability to override the parent if necessary.
You should definitely read on Inheritance and Encapsulation in Object-Oriented Programming.
Since 'child' extends 'main', it now has the members of 'main' in itself. Thus, you would access the properties as local with the arrow operator, as Jonah Bron said.
class child extends main {
function __construct(){
echo $this->$var1;
}
function doSomething(){
$this->db->runQuery();
}
}
A class inherits methods and properties from its parent, but the parent's constructor is not automatically run. You are looking to access the 'db' object but it has not been instantiated. You can manually run the parent's constructor using parent::__construct()
, but beware that your code will currently generate an infinite instantiation loop since you're creating a 'child' from within its parent.
Look at it from the OOP perspective: You have a class bird and a class eagle. The eagle is a bird but not every bird is an eagle. That being said if one uses an object of bird, you only expect a bird not more. So inside a bird class there should be no reference for the calling class or any subclass. Moreover the super class does not know who calls it. It is only allowed to know itself, the super class, implemented interfaces and other classes used for fulfilling it's excercise. These other classes do not include subclasses.
A user of eagle expects an eagle. So this user expects everything a bird has plus some more things. But it creates an eagle object. So it is in the responsibility of the eagle to ensure that it is correctly initialized. Therefore the eagle constructor calls the parent constructor as the very first thing.
<?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();
}
}
精彩评论