Please wait

Abstract Classes

In PHP, an abstract class is a special kind of class that you cannot create an object from. This might seem strange — after all, isn't the purpose of a class to create objects?

Understanding implementation

Before we dive into abstraction classes, let's talk about the general implementations, abstract and concrete implementations.

Let's think about building a LEGO set. When you first open the box, you have a bunch of LEGO blocks and a set of instructions. The instructions tell you how to put the blocks together to create something, like a castle or a car.

In programming, "implementation" is like building that LEGO set. It's the process of taking instructions (like those you get in a programming language) and using them to create something that works.

So, if you're told to write a function that adds two numbers, the implementation is the actual code you write that does the adding. Here's what the implementation might look like in PHP:

function addNumbers($number1, $number2) {
  return $number1 + $number2;
}

In this example, addNumbers() is a function that adds two numbers. The instructions say it needs to take two numbers, add them together, and give back the result. The code inside the function - return $number1 + $number2; - is the implementation. It's the specific way you chose to follow those instructions.

Abstract vs Concrete

Something that is abstract means that it doesn't have a complete implementation. Concrete means that something does have complete implementation.

Let's use an everyday example. Imagine you're looking at a cookbook. The cookbook gives you the recipe for a cake, including a list of ingredients and steps to follow. But the cookbook doesn't actually make the cake, does it? You have to follow the recipe yourself, using actual ingredients, in your kitchen.

In this example, the recipe in the cookbook is like an abstract concept in programming. It outlines what needs to be done but doesn't do it itself. Just like the recipe, an abstract concept in programming gives you a blueprint, but it doesn't do anything on its own.

Recipe Book - Abstract
Recipe Book - Abstract

Now, when you make the cake in your kitchen, that's a concrete implementation. You're taking the abstract concept (the recipe) and making it real. In programming, a concrete implementation is when you write code that actually performs tasks and produces results.

Cake - Concrete
Cake - Concrete

So to sum it up, an abstract concept in programming is like a recipe in a cookbook. It's a blueprint that outlines what needs to be done but doesn't do it itself. A concrete implementation is like baking the cake according to the recipe - it's taking the blueprint and making it real by writing code that performs tasks and produces results.

Defining abstract classes

So, circling back to the subject at hand, abstract classes are not complete classes. They are used as blueprints for other classes.

Imagine you're designing a zoo. Before you start bringing in the animals, you decide to draw up plans for the different habitats. You know that every habitat needs certain elements, like food and water sources, shelter, and space for the animal to move around. But the specifics of these elements will differ depending on the type of animal. For example, a lion needs a different habitat than a penguin.

In this scenario, the general plan for an animal habitat is like an abstract class in PHP (or any object-oriented programming language). An abstract class is a kind of "general plan" for a group of similar objects. It outlines certain features or behavior that all objects of this type should have, but it doesn't provide specific details.

This scenario is perfect for abstract classes. To define an abstract class, we must add the abstract keyword before the class name. Here's how you would define an abstract class in PHP:

abstract class AnimalHabitat {
  abstract public function setFoodSource();
  abstract public function setShelter();
  // ... other methods ...
}

In this example, AnimalHabitat is an abstract class. The abstract keyword tells PHP that this is an abstract class. This class has two abstract methods: setFoodSource and setShelter. The abstract keyword here means that these methods don't have a body; they're just names and parameters, and they don't do anything on their own. The details of what these methods do are not defined in the AnimalHabitat class.

This is because the specific food source and shelter will depend on the type of animal. So, different "concrete" classes (that is, classes that you can actually create objects from) will extend this abstract class and provide the specifics.

Inheriting an abstract class

PHP does not allow us to directly instantiate an abstract class. Abstract classes must always be inherited.

We have our AnimalHabitat abstract class that provides a basic plan for a habitat. But we can't use it directly to create habitats because it's abstract - it's more of an idea than a specific thing.

So, we create specific habitat classes for each animal we want to bring to our zoo. Each specific habitat class will be based on (or "extend") our AnimalHabitat abstract class but will provide the specific details that AnimalHabitat left out.

Let's start with a habitat for lions. We'll create a LionHabitat class that extends AnimalHabitat. Since AnimalHabitat has abstract methods setFoodSource() and setShelter(), we must define these methods in LionHabitat:

class LionHabitat extends AnimalHabitat {
  public function setFoodSource() {
    echo "The food source for lions is meat.";
  }
 
  public function setShelter() {
    echo "The shelter for lions is a large rock.";
  }
}

Now we have a specific habitat for lions! We've used the AnimalHabitat abstract class as a starting point and provided the specific details that lions need in their habitat.

We can do the same thing for penguins:

class PenguinHabitat extends AnimalHabitat {
  public function setFoodSource() {
    echo "The food source for penguins is fish.";
  }
 
  public function setShelter() {
    echo "The shelter for penguins is a nice cold iceberg.";
  }
}

In this way, we use the AnimalHabitat abstract class to create different, specific habitats. Each specific habitat class extends AnimalHabitat, and provides the details needed for a particular animal.

Contracts

Any class that extends an abstract class must implement all of the abstract methods defined in the abstract class. If it doesn't, then it must be declared abstract as well. This is because abstract methods in an abstract class are like a contract that promises certain behavior, and concrete classes that extend the abstract class must fulfill this contract by implementing these behaviors.

Partial implementations

As mentioned before, abstract classes don't need to be completely implemented. This implies that abstract classes can have non-abstract methods.

Let's modify the AnimalHabitat class to include a non-abstract method. In this case, let's add a getSize() method, which can be the same for all habitats:

abstract class AnimalHabitat {
  abstract public function setFoodSource();
  abstract public function setShelter();
 
  public function getSize() {
    echo "The habitat size is 100 square meters.";
  }
}

Now, when we create our specific habitat classes, they still need to implement the abstract methods (setFoodSource() and setShelter()). But they can also use the getSize() method without needing to implement it themselves:

If you now create a new LionHabitat or PenguinHabitat object and call the getSize() method, it will print "The habitat size is 100 square meters." - the implementation provided in the AnimalHabitat abstract class. This is because non-abstract methods in an abstract class provide some default behavior that concrete classes can use.

Key Takeaways

  • Abstract classes are like blueprints. They can declare both abstract methods (which have no implementation and must be implemented by any concrete child class) and non-abstract methods (which do have an implementation).
  • You can't create an object from an abstract class. An abstract class just provides a sort of "template" that other classes can base themselves on.
  • Any class that extends an abstract class must implement all of the abstract methods in the abstract class.
  • Abstract classes can contain non-abstract methods. These methods provide some default behavior that child classes inherit.
  • Abstract classes and methods are defined with the keyword abstract.

Comments

Please read this before commenting