#Lesson 5: Abstraction and Inheritance
##New Keywords:
abstract
extends
parent
"An abstraction denotes the essential characteristics of an object that distinguish it from all other kinds of objects and thus provide crisply defined conceptual boundaries relative to the perspective of the viewer."
##Abstract Classes
An abstract class cannot be instantiated, but rather, child classes can be extended from the abstract class.
Abstract classes are typically used as a means to organize a project. You can't create an object from an abstract class. Instead, a child class extends an abstract class, and then an object can be instantiated from the child class.
The child class must implement all of the abstract methods listed in the parent class. PHP doesn't use abstract properties, only methods, so you can signify an abstract property, but PHP doesn't force you to use it in the implementing classes.
One declares an class as abstract by using the abstract
keyword on both the
class, and any abstract methods must also use the abstract
keyword.
Private methods cannot be declared as abstract, only public or protected methods.
###Example:
<?php
abstract class APerson {
abstract public function getName();
abstract public function setName($name);
public function sayHi() {
return "Hi.\n";
}
}
Abstract classes can have have concrete methods defined. This allows for
classes that only partially need to be implemented by a derived class. In the
example above, the sayHi
concrete method will be available to classes that
extend the APerson
class
If you fail to implement all of the abstract methods outlined in the abstract class in a child concrete class, PHP will throw an error.
Remember that abstract methods are only declarations, and that concrete methods must contain a function body whereas abstract methods must not.
PHP will throw an error if:
- a method in the abstract class isn't implemented in a derived class.
- an implemented method doesn't abide by its signature (parameters)
- the method is of a different visibility than specified
We can extend an abstract into a concrete class by using the extends
keyword:
<?php
class CPerson extends APerson {
public function getName() {
}
public function setName($name) {
}
// Other functions not declared in the abstract class.
public function otherFunc() {
}
}
###Parent
You may find yourself writing code that refers to variables and functions in base classes. This is particularly true if your derived class is a refinement or specialisation of code in your base class.
<?php
class DPerson extends CPerson {
function sayHi() {
$name = $this->getName();
return parent::sayHi() . "My name is {$name}.\n";
}
###Protected: visibility
Another level of visibility (information hiding) is "protected", which means that a protected property or method can be accessed only from within the class defining it, or any subclassses. In contrast, a private property/method is only visible to the class defining it.
<?php
class A {
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
public function testVisibilityA() {
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
// --
$a = new A();
echo $a->public; // Public
echo $a->protected; // Fatal error
echo $a->private; // Fatal error
$a->testVisibilityA(); // Public, Protected, Private
// --
class B extends A {
public function testVisibilityB() {
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
// --
$b = new B();
echo $b->public; // Public
echo $b->protected; // Fatal error
echo $b->private; // Fatal error
$b->testVisibilityA(); // Public, Protected, Private
$b->testVisibilityB(); // Fatal error: subclass can't access $this->private
##Examples in Drupal:
In includes/database.inc
, Drupal defines a abstract DatabaseConnection
class that
extends the PDO class that comes with the PHP PDO extension for it's own
purposes. This abstract class contains many concrete methods as well as
abstract methods.
Different supported databases each extend this DatabaseConnection
class and
then have access to the augmented PDO class, with inherited methods available.
These supported databases then implement the abstract methods declared in the
DatabaseConnection class as they are unique to a given database.
For instance, within the DatabaseConnection
class an abstract queryRange
function is declared. The implementations of this abstract method differ from
MySQL to PostgreSQL as the syntax for range queries differs between the two
databases.
##Exercise:
- Create an abstract class out of the Person class from lesson 2.
- Create a concrete class that extends the abstract class.
- Instantiate an object from the concrete class.
- Set the name of the person object, and then echo it back out.