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:
- Door and alarm are defined using abstract class;
- Door and alarm are defined using interface;
- 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