Inheritance in Dart

Inheritance is a fundamental concept of object-oriented programming (OOP) that allows a class to inherit properties and methods from another class. This promotes code reuse, establishes a hierarchical relationship between classes, and makes it easier to manage and extend code.

Key Concepts of Inheritance

  1. Base Class (Parent Class): The class whose properties and methods are inherited.
  2. Derived Class (Child Class): The class that inherits from the base class. It can add new properties and methods or override existing ones.
  3. Method Overriding: The ability of a derived class to provide a specific implementation of a method that is already defined in its parent class.
  4. Super Keyword: The super keyword is used to refer to the parent class. It can be used to call the parent’s constructor or methods.

Syntax

Basic Inheritance Syntax

class ParentClass {
  // Properties and methods }

class ChildClass extends ParentClass {
  // Additional properties and methods }

Example of Inheritance

Here’s a basic example demonstrating inheritance in Dart:

class Animal {
  String name;

  Animal(this.name);

  void eat() {
    print('$name is eating.');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name); // Calling the parent constructor 
  void bark() {
    print('$name says Woof!');
  }
}

void main() {
  Dog myDog = Dog('Buddy');
  myDog.eat(); // Output: Buddy is eating.   
  myDog.bark(); // Output: Buddy says Woof! 
  }

Explanation

  1. Base Class: The Animal class serves as the base class with a property name and a method eat().
  2. Derived Class: The Dog class extends the Animal class, inheriting its properties and methods.
  3. Constructor: The Dog class uses the super keyword to call the constructor of the Animal class.
  4. Method Call: The derived class can access methods from the base class (eat()) and also define its own methods (bark()).

Method Overriding

Inheritance allows derived classes to override methods from the base class to provide specific implementations.

Example of Method Overriding

class Animal {
  void sound() {
    print('Animal makes a sound');
  }
}

class Cat extends Animal {
  @override   void sound() {
    print('Cat meows');
  }
}

void main() {
  Animal myAnimal = Animal();
  Cat myCat = Cat();

  myAnimal.sound(); // Output: Animal makes a sound   
  myCat.sound(); // Output: Cat meows 
  }

Explanation

  1. Base Class Method: The Animal class has a method sound().
  2. Overriding: The Cat class overrides the sound() method to provide its specific implementation.
  3. @override Annotation: This annotation indicates that the method is overriding a method from the parent class.

Types of Inheritance

 

1. Single Inheritance

Single inheritance occurs when a class inherits from only one parent class. This is the most straightforward form of inheritance and is supported directly by Dart.

Example

class Animal {
  void eat() {
    print('Animal is eating.');
  }
}

class Dog extends Animal {
  void bark() {
    print('Dog barks.');
  }
}

void main() {
  Dog myDog = Dog();
  myDog.eat(); // Output: Animal is eating.   
  myDog.bark(); // Output: Dog barks. 
  }

Explanation

  • Single Inheritance: The Dog class inherits from the Animal class, gaining access to its properties and methods.

2. Multilevel Inheritance

Multilevel inheritance occurs when a class is derived from another derived class, forming a chain of inheritance.

Example

class Animal {
  void eat() {
    print('Animal is eating.');
  }
}

class Dog extends Animal {
  void bark() {
    print('Dog barks.');
  }
}

class Puppy extends Dog {
  void weep() {
    print('Puppy is weeping.');
  }
}

void main() {
  Puppy myPuppy = Puppy();
  myPuppy.eat(); // Output: Animal is eating.   
  myPuppy.bark(); // Output: Dog barks.   
  myPuppy.weep(); // Output: Puppy is weeping. 
  }

Explanation

  • Multilevel Inheritance: The Puppy class inherits from the Dog class, which in turn inherits from the Animal class.

3. Hierarchical Inheritance

Hierarchical inheritance occurs when multiple classes inherit from the same parent class.

Example

class Animal {
  void eat() {
    print('Animal is eating.');
  }
}

class Dog extends Animal {
  void bark() {
    print('Dog barks.');
  }
}

class Cat extends Animal {
  void meow() {
    print('Cat meows.');
  }
}

void main() {
  Dog myDog = Dog();
  Cat myCat = Cat();

  myDog.eat(); // Output: Animal is eating.   myCat.eat(); // Output: Animal is eating.   myDog.bark(); // Output: Dog barks.   myCat.meow(); // Output: Cat meows. }

Explanation

  • Hierarchical Inheritance: Both Dog and Cat classes inherit from the Animal class, sharing its properties and methods.

4. Multiple Inheritance (Not Supported)

Dart does not support multiple inheritance, which is the ability for a class to inherit from more than one parent class. This design choice helps to avoid complexity and ambiguity (the "diamond problem") that can arise with multiple inheritance.

Workaround

While Dart does not allow multiple inheritance, you can achieve similar behavior through the use of mixins.

Example of Mixins

 

mixin CanSwim {
  void swim() {
    print('Swimming');
  }
}

mixin CanFly {
  void fly() {
    print('Flying');
  }
}

class Duck with CanSwim, CanFly {
  void quack() {
    print('Quack');
  }
}

void main() {
  Duck myDuck = Duck();
  myDuck.swim(); // Output: Swimming   
  myDuck.fly();  // Output: Flying   
  myDuck.quack(); // Output: Quack 
  }

Explanation

  • Mixins: The CanSwim and CanFly mixins add swimming and flying capabilities to the Duck class without forming a traditional inheritance chain.

Use Cases for Inheritance

  1. Code Reusability: Inheritance allows you to reuse existing code, reducing redundancy and improving maintainability. For example, if you have a base class Vehicle with common properties and methods, you can create derived classes like Car, Truck, and Bike that inherit from Vehicle.
  2. Polymorphism: Inheritance enables polymorphism, allowing you to treat objects of derived classes as objects of the base class. This is useful in situations where you want to write generic code that works with different types of objects.

     

    void makeSound(Animal animal) {
      animal.sound(); // Calls the appropriate sound method based on the object type 
      }
    
  3. Hierarchical Classification: Inheritance helps in creating a clear, logical structure for your classes, making it easier to understand relationships. For example, you can have a hierarchy like ShapeCircleEllipse.
  4. Extensibility: You can easily extend existing classes by creating new derived classes that inherit the functionality of the base class while adding new features.

Conclusion

Inheritance is a powerful concept in Dart that enhances the ability to create modular, reusable, and maintainable code. Understanding how to use inheritance effectively allows you to build complex systems while keeping your code organized and efficient. By leveraging base and derived classes, method overriding, and polymorphism, you can create a flexible architecture that can adapt to changing requirements. Additionally, understanding the different types of inheritance, including single, multilevel, hierarchical, and the use of mixins for multiple inheritance, will further enhance your coding skills in Dart.

PLAY QUIZ

What is the base class in the context of inheritance?

The class that is derived from another class.

The class that inherits properties and methods from another class.

The class that cannot be instantiated.

The class that contains only static methods.