Abstract classes

Abstract classes are special because they can never be instantiated. Instead, you typically inherit a set of base functionality from them in a new class. For that reason, they are commonly used as the base classes in a larger class hierarchy. In the chapter on inheritance, we created an Animal class and then a Dog class to inherit from the Animal class. In your project, you may very well decide that no one should be able to instantiate the Animal class, because it's too unspecific, but instead use a specific class inheriting from it. The Animal class will then serve as a base class for our own little collection of animals.

A method can be marked as abstract as well. As soon as you mark a class function as abstract, you have to define the class as abstract as well - only abstract classes can hold abstract functions. Another consequence is that you don't have to (and can't) write any code for the function - it's a declaration only. You would do this to force anyone inheriting from your abstract class to implement this function and write the proper code for it. If you don't, PHP will throw an error. However, abstract classes can also contain non-abstract methods, which allows you to implement basic functionality in the abstract class. Let's go on with an example. Here is the abstract class:
abstract class Animal
{
    public $name;
    public $age;
    
    public function Describe()
    {
        return $this->name . ", " . $this->age . " years old";    
    }
    
    abstract public function Greet();
}
As you can see, it looks like a regular exception, but with a couple of differences. The first one is the abstract keyword, which is used to mark both the class it self and the last function as abstract. As mentioned, an abstract function can't contain any body (code), so it's simply ended with a semi-colon as you can see. Now let's create a class that can inherit our Animal class:
class Dog extends Animal
{
    public function Greet()
    {
        return "Woof!";    
    }
    
    public function Describe()
    {
        return parent::Describe() . ", and I'm a dog!";    
    }
}
As you can see, we implement the both functions from the Animal class. The Greet() function we are forced to implement, since it's marked as abstract - it simply returns a word/sound common to the type of animal we are creating. We are not forced to implement the Describe() function - it's already implemented on the Animal class, but we would like to extend the functionality of it a bit. Now, the cool part is that we can re-use the code implemented in the Animal class, and then add to it as we please. In this case, we use the parent keyword to reference the Animal class, and then we call Describe() function on it. We then add some extra text to the result, to clarify which type of animal we're dealing with. Now, let's try using this new class:
$animal = new Dog();
$animal->name = "Bob";
$animal->age = 7;
echo $animal->Describe();
echo $animal->Greet();
Nothing fancy here, really. We just instantiate the Dog class, set the two properties and then call the two methods defined on it. If you test this code, you will see that the Describe() method is now a combination of the Animal and the Dog version, as expected.
<PreviousNext>
^ Back to Top