flutter
/

Dart Abstraction – Abstract Classes and Methods

Last Sync: Today

On this page

10
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

Dart Abstraction – Abstract Classes and Methods

What is Abstraction?

Abstraction is one of the fundamental principles of object‑oriented programming. It means hiding the complex implementation details and showing only the essential features of an object. In Dart, abstraction is achieved using abstract classes and interfaces. Abstraction helps in reducing complexity and isolates the impact of changes.

Abstract Classes

An abstract class is a class that cannot be instantiated directly. It is declared using the abstract keyword. Abstract classes may contain both abstract methods (without a body) and concrete methods (with an implementation). They serve as blueprints for other classes.

DARTRead-only
1
abstract class Animal {
  String name;

  Animal(this.name);

  // Abstract method – no body
  void makeSound();

  // Concrete method
  void sleep() {
    print('$name is sleeping.');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name);

  @override
  void makeSound() {
    print('$name barks.');
  }
}

void main() {
  // Animal a = Animal('pet'); // Error: Cannot instantiate abstract class
  Dog dog = Dog('Buddy');
  dog.makeSound(); // Buddy barks.
  dog.sleep();     // Buddy is sleeping.
}

Abstract Methods

An abstract method is a method declared without an implementation. It must be overridden by any non‑abstract subclass. Abstract methods can only exist inside abstract classes.

DARTRead-only
1
abstract class Shape {
  double area(); // abstract method

  void display() {
    print('Area: ${area()}');
  }
}

class Circle extends Shape {
  double radius;

  Circle(this.radius);

  @override
  double area() => 3.14 * radius * radius;
}

Interfaces (Implicit)

In Dart, every class implicitly defines an interface containing all its instance members. A class can implement one or more interfaces using the implements keyword. When a class implements an interface, it must provide concrete implementations of all members of that interface (even if they were already implemented in the interface class).

DARTRead-only
1
class Flyable {
  void fly() {}
}

class Bird implements Flyable {
  @override
  void fly() {
    print('Bird flies');
  }
}

class Airplane implements Flyable {
  @override
  void fly() {
    print('Airplane flies');
  }
}

Unlike extends, implements does not inherit any implementation – you must provide everything.

Abstract Classes vs Interfaces

Both abstract classes and interfaces help define contracts, but they have differences:

    • An abstract class can have both abstract and concrete methods, and can have fields. It is used when you want to share code among several closely related classes.
    • An interface (via implements) can only declare methods (and getters/setters) but provides no implementation. A class can implement multiple interfaces.
    • In practice, you often use abstract classes as base classes and interfaces to define capabilities.

Using implements with Multiple Interfaces

Dart allows a class to implement multiple interfaces, which is useful for mixing in different capabilities.

DARTRead-only
1
class Swimmable {
  void swim() {}
}

class Walkable {
  void walk() {}
}

class Duck implements Swimmable, Walkable {
  @override
  void swim() {
    print('Duck swims');
  }

  @override
  void walk() {
    print('Duck walks');
  }
}

Abstract Classes with Factory Constructors

Sometimes you need to control object creation. Abstract classes can have factory constructors to return instances of concrete subclasses (e.g., based on some input).

DARTRead-only
1
abstract class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle(5);
    if (type == 'square') return Square(4);
    throw ArgumentError('Unknown shape type');
  }

  double area();
}

class Circle implements Shape {
  double radius;
  Circle(this.radius);
  @override
  double area() => 3.14 * radius * radius;
}

class Square implements Shape {
  double side;
  Square(this.side);
  @override
  double area() => side * side;
}

void main() {
  Shape shape = Shape('circle');
  print(shape.area()); // 78.5
}

Common Mistakes

    • Trying to instantiate an abstract class (compile error).
    • Forgetting to override an abstract method in a concrete subclass (compile error).
    • Using implements when you meant extends – losing code reuse.
    • Making a class abstract unnecessarily.

Complete Example

DARTRead-only
1
abstract class PaymentProcessor {
  void processPayment(double amount);

  void validateAmount(double amount) {
    if (amount <= 0) {
      throw ArgumentError('Amount must be positive');
    }
  }
}

class CreditCardProcessor extends PaymentProcessor {
  @override
  void processPayment(double amount) {
    validateAmount(amount);
    print('Processing credit card payment of \$$amount');
  }
}

class PayPalProcessor extends PaymentProcessor {
  @override
  void processPayment(double amount) {
    validateAmount(amount);
    print('Processing PayPal payment of \$$amount');
  }
}

void main() {
  PaymentProcessor processor = CreditCardProcessor();
  processor.processPayment(100.0);

  processor = PayPalProcessor();
  processor.processPayment(200.0);
}

Key Takeaways

    • Abstraction hides implementation details and exposes only essential features.
    • Abstract classes (declared with abstract) cannot be instantiated and may contain abstract methods.
  • -Abstract methods have no body and must be overridden in concrete subclasses.
    • Every class defines an implicit interface; use implements to enforce that interface.
    • A class can implement multiple interfaces, but can extend only one class.
    • Use abstract classes for code reuse among related classes; use interfaces to define capabilities.

Try it yourself

abstract class Animal {
  void speak();
  void sleep() {
    print('Sleeping...');
  }
}

class Dog extends Animal {
  @override
  void speak() {
    print('Woof!');
  }
}

void main() {
  var dog = Dog();
  dog.speak();
  dog.sleep();
}

Test Your Knowledge

Q1
of 4

Which keyword is used to declare an abstract class in Dart?

A
abstract
B
interface
C
base
D
virtual
Q2
of 4

Can an abstract class be instantiated?

A
Yes
B
No
C
Only if it has no abstract methods
D
Only with a factory constructor
Q3
of 4

What must a concrete subclass do when it extends an abstract class?

A
Override all concrete methods
B
Override all abstract methods
C
Implement at least one method
D
Call the super constructor
Q4
of 4

How many interfaces can a Dart class implement?

A
0
B
1
C
2
D
Any number

Frequently Asked Questions

Can an abstract class have constructors?

Yes, an abstract class can have constructors. They are called when a concrete subclass is instantiated. This is useful for initializing fields defined in the abstract class.

Can an abstract class have fields?

Yes, abstract classes can have instance fields, which are inherited by subclasses. This is one advantage over interfaces (which cannot have fields).

What is the difference between an abstract class and an interface?

An abstract class can provide partial implementation (concrete methods and fields) and can have constructors. An interface (via implements) only declares members – the implementing class must provide all implementations. Also, a class can implement multiple interfaces but extend only one abstract class.

Can I create an instance of an abstract class?

No, you cannot instantiate an abstract class directly. However, you can instantiate a concrete subclass.

Do I have to use the `abstract` keyword for a class that contains an abstract method?

Yes, if a class has at least one abstract method, it must be declared abstract. Otherwise, you'll get a compile error.

Can an abstract class implement an interface?

Yes, an abstract class can implement one or more interfaces using implements. It can then either implement the required methods or leave them abstract for subclasses to implement.

What happens if a concrete class extends an abstract class but doesn't override all abstract methods?

The concrete class must override all abstract methods; otherwise, the class itself becomes abstract and must be declared abstract. The compiler will flag this as an error.

Previous

dart polymorphism

Next

dart encapsulation

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.