Skip to content

OOP: Abstract Classes and Interfaces

Abstract Classes

Abstract classes cannot be instantiated and can contain abstract methods.

dart
abstract class Shape {
  // Abstract method (no implementation)
  double area();
  double perimeter();
  
  // Concrete method
  void display() {
    print('Area: ${area()}, Perimeter: ${perimeter()}');
  }
}

class Circle extends Shape {
  double radius;
  
  Circle(this.radius);
  
  @override
  double area() => 3.14159 * radius * radius;
  
  @override
  double perimeter() => 2 * 3.14159 * radius;
}

class Rectangle extends Shape {
  double width, height;
  
  Rectangle(this.width, this.height);
  
  @override
  double area() => width * height;
  
  @override
  double perimeter() => 2 * (width + height);
}

void main() {
  Shape circle = Circle(5);
  Shape rectangle = Rectangle(4, 6);
  
  circle.display();     // Area: 78.53975, Perimeter: 31.4159
  rectangle.display();  // Area: 24.0, Perimeter: 20.0
}

Interfaces

In Dart, every class implicitly defines an interface. Use implements to implement an interface.

dart
class Flyable {
  void fly() {
    print('Flying');
  }
}

class Swimmable {
  void swim() {
    print('Swimming');
  }
}

class Duck implements Flyable, Swimmable {
  @override
  void fly() {
    print('Duck is flying');
  }
  
  @override
  void swim() {
    print('Duck is swimming');
  }
}

void main() {
  var duck = Duck();
  duck.fly();   // Duck is flying
  duck.swim();  // Duck is swimming
}

Abstract vs Interface

dart
// Abstract class - can have implementation
abstract class Animal {
  void eat() {
    print('Eating...');
  }
  
  void makeSound();  // Abstract method
}

// Interface - must implement all methods
class Walkable {
  void walk() {
    print('Walking');
  }
}

class Dog extends Animal implements Walkable {
  @override
  void makeSound() {
    print('Woof!');
  }
  
  @override
  void walk() {
    print('Dog is walking');
  }
}

Next Steps

Content is for learning and research only.