1. Overview
An interface is a reference type that can be used as a template for classes. When used with a class, an interface enforces a contract that requires a class to provide an implementation for all its methods. On the other hand, a base class is a top-level class. That is, it’s a class from which another class can be derived. Recall that a class is also a reference type used as a template/blueprint for objects. In this short tutorial, let’s see how an interface compares to a base class.
2. Similarities Between an Interface and a Base Class
Let’s see how an interface and a base class are similar:
Interfaces
Base Classes
Inheritance
✓
✓
Polymorphic
✓
✓
Access Modifiers
✓
✓
2.1. Inheritance
Both interfaces and base classes can be inherited by other interfaces or classes. This allows these sub-interfaces or sub-classes to inherit the properties and methods of the super-interface or base class.
2.2. Body and Member Declarations
Both interfaces and base classes can allow for declarations of static and instance variables or methods. Additionally, you can declare nested interfaces or nested classes in either of these reference types.
2.3. Polymorphism
We can override & overload methods defined in either of these reference types.
2.4. Modifiers
Both reference types use access modifiers to limit the visibility of interfaces/classes or their members. However, some visibility modifiers can only be used with interfaces or classes defined within a class, interface, or enum type. This is true for several popular object-oriented languages like C++, PHP, and Java.
3. Differences Between an Interface and a Base Class
Here is a summary of how an interface differs from a base class:
Interfaces
Base Classes
Multiple Inheritance
✓
✓
Create Annotations
✓
✓
3.1. Inheritance
As mentioned earlier, an interface is used to enforce a contract between it and the class that implements it. This implies that if the class doesn’t implement all of the interface’s methods, then the program will give off a compilation error. However, a class that extends a base class is under no obligation to provide an implementation for any abstract methods that it may have. It’s also important to note that depending on the programming language, using an interface may be the only way to achieve multiple inheritance. For example, the only way you can have multiple inheritance in Java and PHP is through interfaces. However, the Solidity programming language allows you to achieve this through subclassing. Interfaces are normally used to specify APIs (Application Programming Interfaces) for a given application. If the API developer/maintainer decided to add more abstract methods, then the developers using this API would have to rewrite their applications to avoid a compilation error. This is, of course, not practical at all. A language like Java can allow you to declare default methods to overcome this challenge. Default methods allow your program to run while ensuring binary compatibility with older versions of your code.
3.2. Classification
There are two types of interfaces that we can use: normal or annotation interface. Normal interfaces are the usual interfaces whose role is simply to act as a blueprint for other interfaces or classes. Annotations, however, are interfaces used to provide metadata to the compiler or other application utilities. Languages like Java and PHP use the @ symbol to denote annotation interfaces (and hence differentiate them from normal interfaces) when used. When it comes to classes, there are also two types: concrete and abstract. Concrete classes are those where all their methods have an implementation. Abstract classes, however, don’t have an implementation for some or all of their methods. It’s important to note that if you are to define any abstract methods in your class, then it automatically is an abstract class.
4. Conclusion
In this article, we reviewed the differences between interfaces and base classes. At this point, you should be wondering when to use a base class or an interface instead. After all, they both act as templates for your classes or interfaces, as we pointed out earlier. You can simply use multiple inheritance or ensure that the methods inherited by a given class must be implemented.