A good example of Abstract class vs. Interface

One of the most frequent question in an interview for a Junior/Graduate Developer role is 'What is the difference between Abstract class and Interface?'. I have to admit that (as a Graduate) I thought this was not a good question to gauge my skill as a developer. I thought my intrepidness or whatever that skill I thought I had was far more important than being able to answer the difference between abstract and interface.



A couple of promotions later, I am sitting at the other end of the table. Having the responsibility of asking that same question, I can start to see to why we need to know the answer.
To know the difference between the two, a developer must think about abstraction and encapsulation; the two paradigm that Object Oriented Programming heavily relies on in modelling reality. Without inheritance and interfaces, we are stuck with complex trees of conditions, iterations and recursions that is probably duplicated again and again to describe a similar characteristic between two entities.

This post will discuss the difference between abstract and interface, along with an (awesome!!!) example - better than you've seen elsewhere.


Abstract class:

  • cannot be instantiated.
  • is a special type of class in which you can have members without implementation.
  • as we know in C#/VB/Java, a class can only inherit from 1 class. This also applies for Abstract Class.
  • normally used for framework-type library classes: providing default behavior for some of its class members, but forcing the developer to implement others.
  • is believed to be faster in Java, HOWEVER I cannot find the same claim in .Net. The speed difference is *probably* negligible and only relevant to the most academic field.
  • the aim: making sure something is *eventually* implemented.
  • A class can inherit an abstract class without implementing all its abstract method.
    However only a class that has all its method implemented can be instantiated to an object.
  • IS-A relationship.
  • e.g. Student IS A Person, Employee IS A Person.
// 'framework library' for a person
// a person can enrol and submit
// however, the class that consume this framework library
// need to provide 'where' the paperwork need to be sent
public abstract Person
{
    public abstract SendPaperWork(string paperwork)

    public void Enrol()
    {
        SendPaperWork("enrolment");
    }

    public void Submit()
    {
        SendPaperWork("report");
    }
}

// by inheriting Person abstract class
// we are enabling student to enrol and submit
// however, SendPaperWork need to be implemented
// because we need to tell it explicitly 'where' 
// to send the enrolment/ submission
public class Student : Person
{
    public override SendPaperWork(string paperwork)
    {
        School.Send(paperwork);
    }
}

// an employee send the paperwork to a different 'place' than student
public class Employee : Person
{
    public override SendPaperWork(string paperwork)
    {
        Company.Send(paperwork);
    }
}

Interface:

  • cannot be instantiated.
  • is a special type of abstract class in which all the members do not have any implementations.
  • enables polymorphism. A class can implement more than 1 Interfaces.
  • normally used for application classes: providing contract for ensuring interactibility.
  • the aim: making sure something is interchangeable.
  • A class that implements an Interface need to contain all the implementation, otherwise the compiler will throw an error.
  • CAN-DO relationship.
  • e.g. Student CAN enrol, Student CAN submit assignment.
public interface ICanEnrol
{
    void Enrol();
}

public interface ICanSubmit
{
    void Submit();
}

public class Student : ICanEnrol, ICanSubmit
{
    public void Enrol()
    {
        School.Send("enrolment");
    }

    public void Submit()
    {
        School.Send("report");
    }
}

public class Employee : ICanEnrol, ICanSubmit
{
    public void Enrol()
    {
        Company.Send("enrolment");
    }

    public void Submit()
    {
        Company.Send("report");
    }
}

public class MailServer
{
    public void SendAllSubmissions()
    {
        // AllSubmitters is a collection of students and employees
        foreach (ICanSubmit submitter in AllSubmitters)
        {
            // The MailServer does not care if 
            // the submitter is a student
            // or an employee, as long as it can submit
            submitter.Submit()
        }
    }
}

With the rise of Aspect Oriented Programming and Domain Specific Language, we are starting to realise that Object Oriented Programming is not even rich enough (or too rich?) to model reality. It is difficult to handle cross cutting concerns using just inheritance and polymorphism. So it's important to master these skills, because the answer is often not obvious. (Unfortunately) It took me a year after Uni (after I got my first job) to feel like I finally grasp these basic object oriented concept.

References

Geeks with blogs. Abstract Class vs Interface
interfaces vs abstract class : Java Glossary