Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface or an Abstract Class: which one to use?

People also ask

Is it better to use interface or abstract class?

If you are creating functionality that will be useful across a wide range of objects, then you must use an interface. Abstract classes, at the end of the day, should be used for objects that are closely related. But the interfaces are best suited for providing common functionality to unrelated cases.

Why do we prefer interface over abstract class?

The main advantages of interface over abstract class is to overcome the occurrence of diamond problem and achieve multiple inheritance. In java there is no solution provided for diamond problem using classes. For this reason multiple inheritance is block using classes in java.

Should I use an interface or a class?

Abstract classes are preferred if the subclasses share some common functionalities with the superclass. Interfaces when you create unrelated classes to implement the interface. Interfaces allow you to implement multiple inheritances. Abstract classes can be extended only once.

When would you use an abstract class instead of an interface java?

Abstract classes should be used for (partial) implementation. They can be a mean to restrain the way API contracts should be implemented. In Java 8 for interface #8, you can have default and static methods too.


Use an interface when you want to force developers working in your system (yourself included) to implement a set number of methods on the classes they'll be building.

Use an abstract class when you want to force developers working in your system (yourself included) to implement a set numbers of methods and you want to provide some base methods that will help them develop their child classes.

Another thing to keep in mind is client classes can only extend one abstract class, whereas they can implement multiple interfaces. So, if you're defining your behavior contracts in abstract classes, that means each child class may only conform to a single contract. Sometimes this a good thing, when you want to force your user-programmers along a particular path. Other times it would be bad. Imagine if PHP's Countable and Iterator interfaces were abstract classes instead of interfaces.

One approach that's common when you're uncertain which way to go (as mentioned by cletus below) is to create an interface, and then have your abstract class implement that interface.


The differences between an Abstract Class and an Interface:

Abstract Classes

An abstract class can provide some functionality and leave the rest for derived class.

  • The derived class may or may not override the concrete functions defined in the base class.

  • A child class extended from an abstract class should logically be related.

Interface

An interface cannot contain any functionality. It only contains definitions of the methods.

  • The derived class MUST provide code for all the methods defined in the interface.

  • Completely different and non-related classes can be logically grouped together using an interface.


Why to use abstract classes? The following is a simple example. Lets say we have the following code:

<?php 

class Fruit {
    private $color;

    public function eat() {
        // chew
    }

    public function setColor($c) {
        $this->color = $c;
    }
}

class Apple extends Fruit {
    public function eat() {
        // chew until core
    }
}

class Orange extends Fruit {
    public function eat() {
        // peeling
        // chew
    }
}

Now I give you an apple and you eat it. What does it taste like? It tastes like an apple.

<?php 
$apple = new Apple();
$apple->eat();

// Now I give you a fruit.
$fruit = new Fruit();
$fruit->eat();

What does that taste like? Well, it doesn't make much sense, so you shouldn't be able to do that. This is accomplished by making the Fruit class abstract as well as the eat method inside of it.

<?php 
abstract class Fruit {
    private $color;

    abstract public function eat(){}

    public function setColor($c) {
        $this->color = $c;
    }
}
?>

An abstract class is just like an interface, but you can define methods in an abstract class whereas in an interface they are all abstract. Abstract classes can have both empty and working/concrete methods. In interfaces, functions defined there cannot have a body. In abstract classes, they can.

A real world example:

<?php 
abstract class person {

    public $LastName;
    public $FirstName;
    public $BirthDate;

    abstract protected function write_info();
}

final class employee extends person{

    public $EmployeeNumber;
    public $DateHired;

    public function write_info(){
        //sql codes here
        echo "Writing ". $this->LastName . "'s info to emloyee dbase table <br>";   
    }
}

final class student extends person{

    public $StudentNumber;
    public $CourseName;

    public function write_info(){
        //sql codes here
        echo "Writing ". $this->LastName . "'s info to student dbase table <br>";
    }
}

///----------
$personA = new employee;
$personB = new student;

$personA->FirstName="Joe";
$personA->LastName="Sbody";

$personB->FirstName="Ben";
$personB->LastName="Dover";

$personA->write_info();
// Writing Sbody's info to emloyee dbase table
$personB->write_info();
// Writing Dover's info to student dbase table 

Best practice is to use an interface to specify the contract and an abstract class as just one implementation thereof. That abstract class can fill in a lot of the boilerplate so you can create an implementation by just overriding what you need to or want to without forcing you to use a particular implementation.


Just to throw this into the mix, but as Cletus mentioned using an interface in conjunction with an abstract class, I often use the interface to clarify my design thinking.

For instance:

<?php
class parser implements parserDecoratorPattern {
    //...
}

That way, anyone reading my code (and who knows what a Decorator Pattern is) will know right away a) how I build my parser and b) be able to see what methods are used to implement the decorator pattern.

Also, and I may be off base here not being a Java/C++/etc programmer, but data types can come into play here. Your objects are of a type, and when you pass them around the type matters programmatically. Moving your contractable items into the interface only dictates the types that the methods return, but not the base type of the class that implements it.

It's late and I can't think of a better psudo-code example, but here goes:

<?php
interface TelevisionControls {};
class Remote implements TelevisionControls {};
class Spouse implements TelevisionControls {};
Spouse spouse = new Spouse();
Remote remote = new Remote();
isSameType = (bool)(remote == spouse)