Today's Question:  What are you most afraid of as a programmer?       GIVE A SHOUT

Technical Article => Programming =>  Java

Should we use Abstract class or Interface?

 sonic0002     2013-04-15 11:44:36      16,336    4    1

When we write programs, we may often get into a situation where we don't know whether we should use Abstract class or Interface when we want to define an abstract object. These two are very similar and they are interchangeable. On Stackoverflow, this question is asked many times, it's related to many programming languages. Also in the official documentation of PHP regarding the Abstract class and Interface, people are arguing about this. To understand this question, we need to understand their differences and use scenarios.

1. Abstract class and Interface structure

For Abstract class:

  1. <?php
  2. abstract class A {
  3.     abstract public function method1();
  4.     abstract public function method2();
  5.     public function method3() {
  6.         //... code ...
  7.     }
  8. }
  9. ?>

For interface:

  1. <?php
  2. interface B {
  3.     public function method4();
  4.     public function method5();
  5. }
  6. ?>

We can see that in abstract class we can have abstract methods such as method1 , method2, and also we can have constructive method such as method3. While in interface we can only declare methods but cannot implement them such as method4 and method5. Obviously if all methods in an abstract class are abstract, then this abstract class degrades to an interface. But to be noted that PHP is similar to Java, one class can only inherit from one abstract class but it can implements multiple interfaces. This is so called single inheritance system. In some other languages such as Python, C++, you can have multiple inheritance.

In abstract class you can declare attribute, but in interface you cannot.

2. Example

Below examples can help us understand the design logic behind abstract class and interface from another aspect. Assume we need to define a class about Door, Door has open and close behavior. Now we can either abstract class or interface.

Abstract class

  1. <?php
  2. abstract class Door {
  3.     abstract public function open();
  4.     abstract public function close();
  5. }
  6. ?>


  1. <?php
  2. interface Door {
  3.     public function open();
  4.     public function close();
  5. }
  6. ?>

In abstract class, we don't implement open and close methods, since some doors need keys to open and some doors need password to open, some other doors may need fingerprint as well, these methods need subclasses to implement. From this aspect, there is no much different on using abstract class or interface.

Now if we define a door which has alarming capability, the definitions can be:

Abstract class

  1. <?php
  2. abstract class Door {
  3.     abstract public function open();
  4.     abstract public function close();
  5.     abstract public function alarm();
  6. }
  7. class AlarmDoor extends Door {
  8.     public function open() {
  9.         //... 
  10.     }
  11.     public function close() {
  12.         //... 
  13.     }
  14.     public function alarm() {
  15.         //... 
  16.     }
  17. }
  18. ?>


  1. <?php
  2. interface Door
  3. {
  4.     public function open();
  5.     public function close();
  6.     public function alerm();
  7. }
  8. class AlarmDoor implements Door {
  9.     public function open() {
  10.         //... 
  11.     }
  12.     public function close() {
  13.         //... 
  14.     }
  15.     public function alarm() {
  16.         //... 
  17.     }
  18. }
  19. ?>

Obviously above methods are not correct, in above definitions we mixed up the open and close behavior of door with the alarm behavior which is not belonging to every door. Some doors can alarm, but some doors may not have this capability. We must define the alarm capability in another object, then we have 3 combinations:

  1. Door and alarm are defined using abstract class;
  2. Door and alarm are defined using interface;
  3. One uses abstract class and the other uses interface

Since subclass in PHP can extend from only one abstract class, and abstract class doesn't support multiple inheritance(abstract class cannot extend abstract class), so the first method is not feasible. The second method doesn't reveal our true design purpose since it doesn't reflect one truth that AlarmDoor is a Door and it has alarm capability. So for Door, we need to use abstract class while for alarm capability we need to use interface.

  1. <?php
  2. abstract class Door {
  3.     abstract function open();
  4.     abstract function close();
  5. }
  6. interface Alarm {
  7.     function alarm();
  8. }
  9. class AlarmDoor extends Door implements Alarm {
  10.     public function open() {
  11.         //... 
  12.     }
  13.     public function close() {
  14.         //... 
  15.     }
  16.     public function alarm() {
  17.         //... 
  18.     }
  19. }
  20. ?>

This reflects our true design purpose. Interface is capable of multiple inheritance, subclass can also implements many interfaces. This can make us continue to enhance the function of the door such as have video camera installed.

3. Conclusion

When we use abstract class, we should declare some attributes of the object, i.e describe what it is. While interface is similar to a plug in, it is more focusing on behavior, i.e what it can do.

Source :





naholyr [Reply]@ 2013-04-18 10:10:21
The key is in your first sentence: "when we want to define an abstract object". Oh, you want to define an *abstract* object. Then you definitely want to define an abstract class. Interface is when you want to define a contract (or a "pattern" of object), not an "abstract object". They're not similar nor interchangeable :( those are two different concepts and the difference is explained in a few seconds (contract ≠ abstract). [Reply]@ 2013-04-18 10:56:20
In PHP 5.4, traits may be a better choice for what you're demonstrating here - you can think of traits as interfaces with a default implementation. So with a trait such as Lockable, you can easily apply both state, interface and behavior such as lock() and unlock() to any Door class, which gives you a great deal more convenience, since you don't have to re-implement the lock() and unlock() methods, and $locked property, as you would have had to with an interface. Another fine choice, instead of either an abstract base-class or an interface, is aggregation - instead of building functionality like lock() and unlock() into the Door, make it an entirely separate class, Lock, encapsulating it's own state ($locked) and it's functionality: lock() and unlock(). Then add an interface Lockable with a method getLock() returning the Lock instance - this way, you can encapsulate both the state and the behavior of the lock. In many scenarios, aggregation is really a better choice than either base-classes or interfaces - while they do still rely on an interface as a means of indicating whether a particular sub-class of Door has a lock, the details of how the Lock works is now encapsulated in a separate class. You could argue that being locked or unlocked is not the Door's responsibility - at the most, the Door may need to know whether the Lock is locked or unlocked, in order to know whether open() succeeds or not, but it doesn't really need to know anything else about the Lock, such as whether a Key might fit. I've always liked the House/Doors/Locks example - it's a useful exercise in abstract thinking :-) [Reply]@ 2013-04-18 10:59:18
PS: fix your comment form please - code blogs receive comments about code, you can't simply ignore whitespace...
sonic0002 [Reply]@ 2013-04-18 12:07:09
Thank you for your suggestion. We will try to fix it by this weekend.


My personal assistant

By sonic0002