Class vs Interface

February 04, 2024

Background - Interface

The term Interface has a very broad meaning. It's any point of connection between two or more entities that facilitates interaction or communication between them. Even the screen on the device that you're using to read this is an interface -- a Graphical User Interface (GUI).

Even though a Class is not an Interface, it does have an interface (in the broad sense of the word): its public methods, because that is how you interact with it.

Overview

A Class is a blueprint for creating an object. A blueprint that defines the behavior of the Class's methods, alongside any data stored in the member variables.

An Interface, in the context of programming, is a contract such that any class that implements that Interface must implement, at a minimum, the public methods defined in that Interface. This is very useful for the Polymorphism that it provides.

Table of Contents

Polymorphism
Closer Look
Class
Interface
Composition vs Inheritance
Conclusion

Polymorphism
^

Polymorphism is the ability for something to take multiple forms. Both Classes and Interfaces can utilize Polymorphism.

  • Interface: When an interface is referenced for a variable, any class that implements it can take that place.
  • Class: When a parent class is referenced for a variable, any subclass can take that place.

Defining Interface Polymorphism:

interface Shape {
    void draw();
}

class Circle implements Shape {
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

class Rectangle implements Shape {
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}

Defining Class Polymorphism:

class Animal {
    void makeSound() {
        System.out.println("Some generic sound");
    }
}

class Dog extends Animal {
    void makeSound() {
        System.out.println("Bark");
    }
}

class Cat extends Animal {
    void makeSound() {
        System.out.println("Meow");
    }
}

Demonstrating both Interface and Class Polymorphism:

public class PolymorphismDemo {
    public static void start() {
        // Interface polymorphism
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        
        circle.draw();    // Output: Drawing a circle
        rectangle.draw(); // Output: Drawing a rectangle

        // Class inheritance polymorphism
        Animal dog = new Dog();
        Animal cat = new Cat();
        
        dog.makeSound(); // Output: Bark
        cat.makeSound(); // Output: Meow
        
        // Array of shapes
        Shape[] shapes = new Shape[] {new Circle(), new Rectangle()};
        for (Shape shape : shapes) {
            shape.draw(); // Calls the draw method of each shape
        }

        // Array of animals
        Animal[] animals = new Animal[] {new Dog(), new Cat()};
        for (Animal animal : animals) {
            animal.makeSound(); // Calls the makeSound method of each animal
        }
    }
}

Examples generated by ChatGPT of OpenAI and modified.

These Java constructs above don't actually draw or make sounds. They just print. You can easily run the above in jshell on your machine by copy/pasting the code and calling the static function: PolymorphismDemo.start().

A deeper dive into Polymorphism can be found here.

Closer Look
^

Class
^

  • Encapsulation: Classes encapsulate behavior through their methods and data through their member variables.
  • Inheritance: Classes inherit member variables and methods from all of their parent classes.
  • Instantiation: Classes are blueprints that can be instantiated into objects.

Some languages have the construct of abstract Classes that provides some base functionality, but cannot be instantiated -- it must be sub-classed. These base methods cannot be modified by their children classes.

Interface
^

  • Abstraction: Interfaces provide a high degree of abstraction. By only defining the signatures of methods, the implementation can be entirely unique.
  • Implementation: In most programming languages, Classes can only inherit from a single parent Class (e.g. Java, but this is not the case in Python). However, in most programming languages, Classes can inherit from multiple Interfaces.
  • Flexibility: Class hierarchies are very rigid. If you need to change the behavior of a method in a parent class, it will affect all children classes. Interfaces typically don't have a hierarchy of behavior, but they can if they're extended like classes.

Since Java 8, Interfaces are able to support default implementations where you can provide an implementation of a method so that it doesn't need to be implemented in the implementing class.

Composition vs Inheritance
^

Always favor composition over inheritance. This is due to the fact that requiring a change in a parent class can have large scale cascading effects throughout its children classes. Composition provides flexibility because it's easier to change arguments of a function.

Learn more about Composition vs Inheritance.

Conclusion
^

Classes are the hallmark of Object-Oriented Programming. On the other hand, Interfaces exist in languages that don't support OOP (e.g. Golang).