Warning: extremely nerdy content follows.

Object oriented programming is all the rage these days and PHP provides a fairly complete toolkit to be down with OOP (that's Object Oriented Programming for non nerds). PHP has gained in popularity for this very reason. However, most of us don't really go very deep into different OOP features like interface classes and abstract classes. We wade in the shallow waters of plain old basic classes, either intimidated by or oblivious to the depths that OOP has to offer.

It's time to get out of the kiddie pool... we're going deep.

Let's look at "abstract classes." While they don't make for great party conversation, they are a powerful tool if used correctly. Let's create an example.

You need a class for users, which might look like this in it's simplest form.

class Users {public $username;public $password;...function __construct() {...}static function login($username, $password) {...}public function logout() {...}}

Simple enough. But what if you need more than one type of user such as sales and customer? You could create two classes, one for each. The downside of that approach is you will have to maintain two different database tables and two classes. That means if any changes have to happen, such as adding in a captcha, it has to happen in more than one place. You would then have to change both classes and both tables. It can get messy.

Abstract classes to the rescue!

Abstract classes allow you to have a common set of functions shared by all the classes that are extended from it.abstract class Users {public $username;public $password;...function __construct() {...}function login($username, $password) {...}function logout() {...}abstract function checkSale();}Notice we added a function here, but it's set as abstract, it has no brackets ({}), and ends with a semi-colon. We also made sure to initiate the constructor for the parent class with "parent::__construct()" (be sure to pass any variables needed by the parent class). Now comes the fun. We can create two separate classes that extend this class and add all sorts of functionality to each of them, but still inherit everything we've already created. In our example that would be "Customers" and "Sales".

Now those who know a bit about OOP may ask, "why don't we just create a normal class and extend it then?" First off, someone could still use the parent "User" class. This can create instability in the system since not all User objects would be created as Customers and Sales objects, but as the parent (Users). While YOU may know what you are doing, a programmer who follows you may end up pulling out hair and calling down curses on your head.

With an abstract class we don't have to worry about that. You can't create an object using an abstract class. You have to extend the class AND make sure to write a function for any of those abstract function lines we have in the parent class. If we don't, PHP will throw an error. Here's an example of a derived class.

class Sales extends Users {public $salesGoal;public $currentSales;...function __construct() {parent::__construct();}function addSale($amount) {...}// Here's the abstract functionfunction checkSale() {... // make sure the sale happened, etc.}}

And the Customer class:

class Customer extends Users {public $lastSale;public $lastProduct;function __construct() {parent::__construct();}function addPurchase($item, $amount) {...}// Here's the abstract functionfunction checkSale() {... // do some other validation}}

Now we have two independent classes that share functionality and each have unique functionality. Neat! Let's look at the pros and cons for abstract classes:

Pros

  • You can have multiple classes that share functionality.
  • The parent class can't be used to create objects, keeping things tidy and simple.
  • You can add shared functionality simply.
Cons
  • You can't use the parent class, reducing flexibility.
  • If you don't have a compelling reason to use abstract classes, you are introducing complexity instead of keeping it simple.
  • You have to use EVERY abstract function in a derived class, whether you need it or not.