Should we use Abstract class or Interface?

  sonic0002        2013-04-15 11:44:36       21,893        5    

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 in many cases. On Stackoverflow, this question is asked lots of times and 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, their differences and use scenarios need to be understood first.

Abstract class and Interface structure

For Abstract class:

<?php
abstract class A {
    abstract public function method1();
    abstract public function method2();
    public function method3() {
        //... code ...
    }
}
?>

For interface:

<?php
interface B {
    public function method4();
    public function method5();
}
?>

In abstract class, abstract methods such as method1 and method2 can be defined, and also normal method with implementation such as method3 can also be defined. While in interface, methods can only be declared but cannot be implemented such as method4 and method5, their methods have to be implemented by their subclasses. 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 implement multiple interfaces. This is so called single inheritance system. In some other languages such as Python, C++, you can have multiple inheritance.

Attributes can be declared in abstract class but not in interface though interface allows constants.

Example

Below examples can help understand the design logic behind abstract class and interface from another aspect. Assume a class about Door needs to be defined, Door has open and close behavior. Now either abstract class or interface can be used.

Abstract class

<?php
abstract class Door {
    abstract public function open();
    abstract public function close();
}
?>

Interface

<?php
interface Door {
    public function open();
    public function close();
}
?>

In abstract class, open and close methods are abstract 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 to be implemented by its subclasses. There is no much different on using abstract class or interface in this regard.

Now if a door which has alarming capability is to be defined, the definitions can be:

Abstract class

<?php
abstract class Door {
    abstract public function open();
    abstract public function close();
    abstract public function alarm();
}
class AlarmDoor extends Door {
    public function open() {
        //... 
    }
    public function close() {
        //... 
    }
    public function alarm() {
        //... 
    }
}
?>

Interface

<?php
interface Door
{
    public function open();
    public function close();
    public function alerm();
}
class AlarmDoor implements Door {
    public function open() {
        //... 
    }
    public function close() {
        //... 
    }
    public function alarm() {
        //... 
    }
}
?>

Obviously above definitions are not ideal, the open and close behavior of door are messed up with the alarm behavior which is not belonging to every door in above definitions . Some doors can alarm, but some doors may not have this capability. The alarm capability must be defined in another object, then 3 combinations are available:

  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 the 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.

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

Conclusion

When using abstract class, we would expect to 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.

Reference : http://cloudbbs.org/forum.php?mod=viewthread&tid=13433

COMPARISON  OOP  DIFFERENCE  INTERFACE  ABSTRACT CLASS 

       

  RELATED


  5 COMMENTS


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).
blog.mindplay.dk [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 :-)
blog.mindplay.dk [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.
brianmanee [Reply]@ 2016-04-26 01:07:30

 

An abstract class cannot support multiple inheritance, but an interface can support multiple inheritance. Thus a class may inherit several interfaces but only one abstract class.

An interface is an empty shell, just only the signatures of the methods. The methods do not contain anything. The interface can't do anything. It's just a pattern. An Abstract class is a class which will contains both definition and implementation in it. More about....Abstract Class and Interface

Brian

 



  RANDOM FUN

Advantage of decoupling