Dart: Abstract class & method

Vinit MepaniVinit Mepani
4 min read

To define a class that doesn’t require a full, concrete implementation of its entire interface, use the abstract modifier.

Abstract classes cannot be constructed from any library, whether its own or an outside library. Abstract classes often have abstract methods.

We can not create object of abstract class, for access Abstract class and method we have to extend abstract to another class and create object to other class , then we can access all the element of Abstract class.


// Objectives
// 1. Abstract Method
// 2. Abstract Class

void main() {

//    var shape = Shape();        // Error. Cannot instantiate Abstract Class

    var circle = Circle();
    circle..draw()..circleArea();
}

abstract class Shape {

    // Define your Instance variable if needed
    int x =5;


    void draw();        // Abstract Method

    void circleArea() {
      print("Circle Area is ${3.14*x*x}");
    }
}


class Circle extends Shape {

    void draw() {
        print("Calacute Circle Area.....");
    }
}

Dart Abstract Class: Treating Concrete Classes as Abstract

Dart, known for its flexibility and expressive syntax, offers developers various ways to design and structure their code. One intriguing approach that might not adhere strictly to conventional wisdom is treating concrete classes as abstract. In this exploration, we'll delve into the concept of Dart abstract classes, understand their conventional use, and then break some norms by considering how concrete classes can be treated with an abstract mindset.

Understanding Dart Abstract Classes

In Dart, abstract classes play a pivotal role in facilitating polymorphism and code organization. An abstract class serves as a blueprint for other classes, providing a common interface and potentially containing abstract methods—methods without a default implementation. Concrete subclasses must implement these abstract methods, ensuring adherence to the defined structure.

abstract class Shape {
  void draw(); // Abstract method
}

class Circle extends Shape {
  @override
  void draw() {
    print('Drawing a Circle');
  }
}

class Square extends Shape {
  @override
  void draw() {
    print('Drawing a Square');
  }
}

In this standard usage, the Shape abstract class defines an abstract method draw, which concrete subclasses like Circle and Square must implement.

Breaking Conventions: Treating Concrete Classes as Abstract

Now, let's venture into unconventional territory—treating concrete classes as abstract. While Dart doesn't explicitly support the abstract keyword for concrete classes, we can adopt a mindset where a base concrete class provides default implementations that can be either overridden or extended by its subclasses.

class Animal {
  void makeSound() {
    print('Some generic sound');
  }

  void eat() {
    print('Eating...');
  }
}

class Dog extends Animal {
  @override
  void makeSound() {
    print('Bark! Bark!');
  }

  void fetch() {
    print('Fetching the ball');
  }
}

Here, Animal is a concrete class with default implementations for makeSound and eat. The Dog class, as a subclass of Animal, inherits these behaviors and can choose to override or extend them.

Use Cases for Treating Concrete Classes as Abstract

1. Providing Sensible Defaults

Treating concrete classes as abstract can be particularly useful when you want to offer sensible default implementations for certain methods while still allowing subclasses to customize or extend the behavior.

class BaseController {
  void initialize() {
    print('BaseController initialized');
    // Additional initialization logic
  }

  void performAction() {
    print('Performing default action');
    // Default action logic
  }
}

class CustomController extends BaseController {
  @override
  void initialize() {
    super.initialize();
    print('CustomController initialized');
    // Additional initialization logic specific to CustomController
  }

  @override
  void performAction() {
    super.performAction();
    print('Performing custom action');
    // Custom action logic
  }
}

In this scenario, BaseController provides default implementations for initialize and performAction. Subclasses like CustomController can override these methods based on their specific requirements.

2. Gradual Refactoring

Treating concrete classes as abstract can be part of a gradual refactoring process. If you have existing concrete classes that you want to make more extensible, introducing a base class with default implementations allows you to migrate subclasses gradually.

Considerations and Best Practices

While treating concrete classes as abstract offers flexibility, it's essential to consider some best practices:

  1. Documentation: Clearly document the intention and design decisions behind treating concrete classes as abstract. This unconventional approach may deviate from standard patterns, so providing guidance for developers is crucial.

  2. Code Reviews: Incorporate discussions about the rationale behind treating concrete classes as abstract in your code reviews. This helps maintain code readability and a shared understanding within the development team.

  3. Consistency: If you choose to adopt this approach, strive for consistency in its application across the codebase. Consistent use helps developers understand and predict class behaviors.

  4. Testing: Thoroughly test subclasses to ensure that they behave as expected. While default implementations in the base class aim to provide sensible behavior, subclasses might introduce additional complexities.

0
Subscribe to my newsletter

Read articles from Vinit Mepani directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Vinit Mepani
Vinit Mepani

"Hello World, I'm Vinit Mepani, a coding virtuoso driven by passion, fueled by curiosity, and always poised to conquer challenges. Picture me as a digital explorer, navigating through the vast realms of code, forever in pursuit of innovation. In the enchanting kingdom of algorithms and syntax, I wield my keyboard as a magical wand, casting spells of logic and crafting solutions to digital enigmas. With each line of code, I embark on an odyssey of learning, embracing the ever-evolving landscape of technology. Eager to decode the secrets of the programming universe, I see challenges not as obstacles but as thrilling quests, opportunities to push boundaries and uncover new dimensions in the realm of possibilities. In this symphony of zeros and ones, I am Vinit Mepani, a coder by passion, an adventurer in the digital wilderness, and a seeker of knowledge in the enchanting world of code. Join me on this quest, and let's create digital wonders together!"