Question #74EasyDart Basics

What is Object Oriented Programming in Dart: Abstraction ?

#dart

Answer

Overview

Abstraction is the OOP principle of hiding complex implementation details and exposing only the essential interface. In Dart, abstraction is achieved through abstract classes and interfaces.


Abstract Class

An abstract class cannot be instantiated — it defines a contract that subclasses must fulfill.

dart
// Abstract class — cannot be instantiated directly
abstract class Shape {
  // Abstract methods — no implementation (must be overridden)
  double area();
  double perimeter();

  // Concrete method — shared by all subclasses
  void describe() {
    print('Area: ${area().toStringAsFixed(2)}, Perimeter: ${perimeter().toStringAsFixed(2)}');
  }
}

class Circle extends Shape {
  final double radius;
  Circle(this.radius);

  
  double area() => 3.14159 * radius * radius;

  
  double perimeter() => 2 * 3.14159 * radius;
}

class Rectangle extends Shape {
  final double width, height;
  Rectangle(this.width, this.height);

  
  double area() => width * height;

  
  double perimeter() => 2 * (width + height);
}

void main() {
  // final shape = Shape(); // ❌ Cannot instantiate abstract class

  final shapes = [Circle(5), Rectangle(4, 6)];
  for (final s in shapes) s.describe(); // Polymorphic — abstraction in action
}

Interface (abstract class + implements)

Dart uses abstract classes as interfaces:

dart
// Interface — pure abstraction (all abstract methods)
abstract class DatabaseAdapter {
  Future<void> connect(String url);
  Future<List<Map>> query(String sql);
  Future<void> close();
}

// SQLite implementation
class SQLiteAdapter implements DatabaseAdapter {
   Future<void> connect(String url) async { /* SQLite connect */ }
   Future<List<Map>> query(String sql) async { return []; }
   Future<void> close() async { /* Close */ }
}

// Firestore implementation
class FirestoreAdapter implements DatabaseAdapter {
   Future<void> connect(String url) async { /* Firestore connect */ }
   Future<List<Map>> query(String sql) async { return []; }
   Future<void> close() async { /* Close */ }
}

// Business logic only knows about the interface — not the implementation
class UserRepository {
  final DatabaseAdapter _db; // Abstraction — not concrete impl
  UserRepository(this._db);

  Future<List<Map>> getUsers() => _db.query('SELECT * FROM users');
}

Abstract vs Interface vs Mixin

Feature
text
abstract class
text
interface
(abstract class)
text
mixin
Can have implementation✅ Yes❌ No (by convention)✅ Yes
Instantiable❌ No❌ No❌ No
Used with
text
extends
text
implements
text
with
MultipleOne
text
extends
Many
text
implements
Many
text
with

Real benefit: Abstraction lets you change the underlying implementation (swap SQLite for Firestore) without changing any business logic code — as long as the interface is honored.