Understanding Interfaces and Abstract Classes with programming and real-world examples.
An interface defines a set of methods (functions) that a class must implement, but it does not provide any code (implementation) itself. In Dart, every class implicitly defines an interface. You can create a class that implements an interface to promise it will provide those methods.
Imagine a RemoteControl interface for electronic devices. Any device like a TV, Fan, or AC that wants to be controlled by a remote must have methods like turnOn() and turnOff().
The interface just lists these actions, but each device will do it differently.
abstract class RemoteControl {
void turnOn();
void turnOff();
}
class TV implements RemoteControl {
@override
void turnOn() {
print('TV is now ON');
}
@override
void turnOff() {
print('TV is now OFF');
}
}
void main() {
TV myTV = TV();
myTV.turnOn();
myTV.turnOff();
}
Here, RemoteControl is an interface with two methods. TV implements it and provides code for those methods.
An abstract class is a class that cannot be directly instantiated (you cannot create objects from it). It can have both implemented methods and methods without implementation (abstract methods). Abstract classes are used to define a base class with some shared code and enforce subclasses to provide specific implementations.
Think of an Animal abstract class. All animals breathe, but how they make sounds is different.
So, Animal can have a shared method breathe() and an abstract method makeSound() that subclasses like Dog or Cat must implement.
abstract class Animal {
void breathe() {
print('Breathing...');
}
void makeSound(); // Abstract method
}
class Dog extends Animal {
@override
void makeSound() {
print('Bark! Bark!');
}
}
void main() {
Dog dog = Dog();
dog.breathe(); // Inherited method
dog.makeSound(); // Implemented abstract method
}
You cannot create Animal directly, but Dog extends it and must implement makeSound().
Interfaces and abstract classes help organize your code by defining clear contracts or base behaviors. They allow different classes to share the same interface or base class but implement details their own way.