What is Inheritance?
Inheritance is a fundamental concept in object-oriented programming (OOP) where a new class (subclass or child class) inherits properties and behaviors from an existing class (superclass or parent class).
This promotes code reusability and helps organize code into a hierarchical structure.
Key Concepts
Inheritance: Establishing a parent-child relationship between classes.
Superclass (Parent): The base class that provides properties and methods.
Subclass (Child): The class that inherits from the superclass.
Overriding: Redefining a method in the subclass with a different implementation.
Benefits of Inheritance
Code Reusability: Avoids code duplication by inheriting common properties and methods.
Code Organization: Creates a clear hierarchical structure for classes.
Extensibility: Easily add new features or modify existing behavior in subclasses.
In Summary
Inheritance is a powerful tool in Dart that allows you to create a more organized and efficient codebase by leveraging existing class definitions and promoting code reusability.
class Animal
{
void makeSound() {
print('Generic animal sound');
}
}
class Dog extends Animal
{
@override
void makeSound() {
print('Woof!');
}
}
void main()
{
Dog myDog = Dog();
myDog.makeSound(); // Output: Woof!
}
Explanation:
Base Class (Animal):
The Animal class is the base class.
It has a method makeSound() that prints a generic animal sound.
Derived Class (Dog)
The Dog class extends the Animal class, meaning it inherits all the properties and methods of the Animal class.
The Dog class overrides the makeSound() method to provide a specific sound for dogs ("Woof!").
Object Creation and Method Call:
An object myDog is created from the Dog class.
When myDog.makeSound() is called, it executes the makeSound() method defined specifically for the Dog class.
Inheritance is one of the core concepts of Object-Oriented Programming (OOP). It allows a class to inherit properties and methods from another class. In Dart, the extends keyword is used to implement inheritance, enabling you to create a new class based on an existing class.
Here's an overview of inheritance in Dart:
Base Class (Parent Class): This is the class whose properties and methods are inherited.
Derived Class (Child Class): This is the class that inherits properties and methods from the base class.
Key Points:
A child class can access all non-private members of the parent class.
The child class can override methods in the parent class to provide specific functionality.
Constructors are not inherited by default, but a child class can call the parent class constructor using super().
1. Simple Inheritance Example
class Animal {
String name;
Animal(this.name);
void speak() {
print("$name makes a sound.");
}
}
class Dog extends Animal {
Dog(String name) : super(name);
@override
void speak() {
print("$name barks.");
}
}
void main() {
var dog = Dog("Buddy");
dog.speak(); // Output: Buddy barks.
}
In this example:
Animal is the base class with a name property and a speak() method.
Dog is the derived class that extends Animal and overrides the speak() method.
2. Constructor Inheritance and Initialization
class Person {
String name;
int age;
// Constructor of the base class
Person(this.name, this.age);
void introduce() {
print("Hello, I am $name and I am $age years old.");
}
}
class Student extends Person {
String school;
// Constructor of the derived class
Student(String name, int age, this.school) : super(name, age);
@override
void introduce() {
super.introduce();
print("I study at $school.");
}
}
void main() {
var student = Student("Alice", 20, "XYZ University");
student.introduce();
// Output:
// Hello, I am Alice and I am 20 years old.
// I study at XYZ University.
}
In this example:
The Student class uses super() to call the constructor of the base class Person.
The introduce() method is overridden in the Student class to add additional functionality.
3. Method Overriding
class Vehicle {
void start() {
print("Vehicle is starting.");
}
}
class Car extends Vehicle {
@override
void start() {
print("Car is starting with keyless entry.");
}
}
void main() {
var car = Car();
car.start(); // Output: Car is starting with keyless entry.
}
In this example:
The Car class overrides the start() method of the Vehicle class to provide its own implementation.
The @override annotation ensures that the method is correctly overridden.
4. Inheritance with Multiple Levels
class Shape {
void draw() {
print("Drawing a shape.");
}
}
class Circle extends Shape {
@override
void draw() {
print("Drawing a circle.");
}
}
class ColoredCircle extends Circle {
String color;
ColoredCircle(String color) : color = color;
@override
void draw() {
super.draw();
print("The color is $color.");
}
}
void main() {
var coloredCircle = ColoredCircle("Red");
coloredCircle.draw();
// Output:
// Drawing a circle.
// The color is Red.
}
In this example:
ColoredCircle extends Circle, which in turn extends Shape, creating a multilevel inheritance structure.
ColoredCircle overrides the draw() method, calling the draw() method from Circle using super.draw().
5. Using super() for Accessing Parent Class Members
class Animal {
String name;
Animal(this.name);
void speak() {
print("$name makes a sound.");
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void speak() {
super.speak(); // Calls Animal's speak method
print("$name barks.");
}
}
void main() {
var dog = Dog("Buddy");
dog.speak();
// Output:
// Buddy makes a sound.
// Buddy barks.
}
In this example:
super.speak() is used to call the speak() method of the parent class Animal before adding additional functionality in the Dog class.
6. Inheritance with Private Members
class Animal {
String name;
int _age; // Private member
Animal(this.name, this._age);
void showDetails() {
print("Name: $name, Age: $_age");
}
}
class Dog extends Animal {
Dog(String name, int age) : super(name, age);
void showDogDetails() {
// print("Age: $_age"); // Error: _age is private in Animal class
print("Dog's Name: $name");
}
}
void main() {
var dog = Dog("Buddy", 3);
dog.showDetails(); // Output: Name: Buddy, Age: 3
dog.showDogDetails(); // Output: Dog's Name: Buddy
}
In this example:
The Animal class has a private member _age, which is not directly accessible by the Dog class.
The Dog class can still access the public name but cannot directly access _age.
7. Inheritance with super in a Constructor
class Animal {
String name;
Animal(this.name);
void display() {
print("Animal Name: $name");
}
}
class Dog extends Animal {
int age;
Dog(String name, this.age) : super(name);
@override
void display() {
super.display();
print("Dog Age: $age");
}
}
void main() {
var dog = Dog("Max", 5);
dog.display();
// Output:
// Animal Name: Max
// Dog Age: 5
}
In this example:
The Dog class extends Animal and calls the Animal constructor using super(name).
The display() method is overridden in the Dog class to display additional information.
Base and Derived Classes: A derived class inherits properties and methods from the base class.
Method Overriding: Derived classes can override methods from the base class to provide specialized behavior.
Constructor Inheritance: A derived class can call a constructor of the base class using super().
Access to Parent Class Members: Derived classes can access non-private members of the base class, but private members are not directly accessible.
Super Keyword: super is used to refer to the parent class, both for calling methods and constructors.
In single inheritance, a subclass inherits from only one superclass.
1. Single Inheritance with Animal and Dog
class Animal {
void sound() {
print("Animal makes a sound");
}
}
class Dog extends Animal {
void bark() {
print("Dog barks");
}
}
void main() {
Dog dog = Dog();
dog.sound();
dog.bark();
}
2. Single Inheritance with Vehicle and Car
class Vehicle {
void start() {
print("Vehicle started");
}
}
class Car extends Vehicle {
void drive() {
print("Car is driving");
}
}
void main() {
Car car = Car();
car.start();
car.drive();
}
3. Single Inheritance with Shape and Circle
class Shape {
void draw() {
print("Drawing shape");
}
}
class Circle extends Shape {
void drawCircle() {
print("Drawing circle");
}
}
void main() {
Circle circle = Circle();
circle.draw();
circle.drawCircle();
}
4. Single Inheritance with Person and Student
class Person {
void introduce() {
print("I am a person");
}
}
class Student extends Person {
void study() {
print("I am studying");
}
}
void main() {
Student student = Student();
student.introduce();
student.study();
}
In multilevel inheritance, a class is derived from a class which is also derived from another class.
5. Multilevel Inheritance with Animal, Mammal, and Dog
class Animal {
void sound() {
print("Animal makes a sound");
}
}
class Mammal extends Animal {
void breathe() {
print("Mammal breathes");
}
}
class Dog extends Mammal {
void bark() {
print("Dog barks");
}
}
void main() {
Dog dog = Dog();
dog.sound();
dog.breathe();
dog.bark();
}
6. Multilevel Inheritance with Employee, Manager, and Director
class Employee {
void work() {
print("Employee is working");
}
}
class Manager extends Employee {
void manage() {
print("Manager is managing");
}
}
class Director extends Manager {
void makeDecisions() {
print("Director makes decisions");
}
}
void main() {
Director director = Director();
director.work();
director.manage();
director.makeDecisions();
}
7. Multilevel Inheritance with Machine, Vehicle, and Car
class Machine {
void operate() {
print("Machine is operating");
}
}
class Vehicle extends Machine {
void start() {
print("Vehicle started");
}
}
class Car extends Vehicle {
void drive() {
print("Car is driving");
}
}
void main() {
Car car = Car();
car.operate();
car.start();
car.drive();
}
8. Multilevel Inheritance with LivingBeing, Plant, and Flower
class LivingBeing {
void live() {
print("Living being lives");
}
}
class Plant extends LivingBeing {
void grow() {
print("Plant grows");
}
}
class Flower extends Plant {
void bloom() {
print("Flower blooms");
}
}
void main() {
Flower flower = Flower();
flower.live();
flower.grow();
flower.bloom();
}
In hierarchical inheritance, multiple subclasses inherit from a single superclass.
9. Hierarchical Inheritance with Animal, Dog, and Cat
class Animal {
void sound() {
print("Animal makes a sound");
}
}
class Dog extends Animal {
void bark() {
print("Dog barks");
}
}
class Cat extends Animal {
void meow() {
print("Cat meows");
}
}
void main() {
Dog dog = Dog();
Cat cat = Cat();
dog.sound();
dog.bark();
cat.sound();
cat.meow();
}
10. Hierarchical Inheritance with Shape, Circle, and Rectangle
class Shape {
void draw() {
print("Drawing shape");
}
}
class Circle extends Shape {
void drawCircle() {
print("Drawing circle");
}
}
class Rectangle extends Shape {
void drawRectangle() {
print("Drawing rectangle");
}
}
void main() {
Circle circle = Circle();
Rectangle rectangle = Rectangle();
circle.draw();
circle.drawCircle();
rectangle.draw();
rectangle.drawRectangle();
}
11. Hierarchical Inheritance with Vehicle, Car, and Bike
class Vehicle {
void start() {
print("Vehicle started");
}
}
class Car extends Vehicle {
void drive() {
print("Car is driving");
}
}
class Bike extends Vehicle {
void ride() {
print("Bike is riding");
}
}
void main() {
Car car = Car();
Bike bike = Bike();
car.start();
car.drive();
bike.start();
bike.ride();
}
class Employee {
void work() {
print("Employee is working");
}
}
class Developer extends Employee {
void develop() {
print("Developer is coding");
}
}
class Tester extends Employee {
void test() {
print("Tester is testing");
}
}
void main() {
Developer developer = Developer();
Tester tester = Tester();
developer.work();
developer.develop();
tester.work();
tester.test();
}
Dart doesn't support multiple inheritance, but mixins allow you to add multiple behaviors to a class.
13. Mixin Example with Swimmer and Flyer
mixin Swimmer {
void swim() {
print("Swimming");
}
}
mixin Flyer {
void fly() {
print("Flying");
}
}
class Duck with Swimmer, Flyer {}
void main() {
Duck duck = Duck();
duck.swim();
duck.fly();
}
14. Mixin Example with Eater and Sleeper
mixin Eater {
void eat() {
print("Eating");
}
}
mixin Sleeper {
void sleep() {
print("Sleeping");
}
}
class Human with Eater, Sleeper {}
void main() {
Human human = Human();
human.eat();
human.sleep();
}
15. Mixin Example with Walker and Runner
mixin Walker {
void walk() {
print("Walking");
}
}
mixin Runner {
void run() {
print("Running");
}
}
class Athlete with Walker, Runner {}
void main() {
Athlete athlete = Athlete();
athlete.walk();
athlete.run();
}
16. Mixin Example with Reader and Writer
mixin Reader {
void read() {
print("Reading");
}
}
mixin Writer {
void write() {
print("Writing");
}
}
class Author with Reader, Writer {}
void main() {
Author author = Author();
author.read();
author.write();
}
17. Mixin Example with Painter and Sculptor
mixin Painter {
void paint() {
print("Painting");
}
}
mixin Sculptor {
void sculpt() {
print("Sculpting");
}
}
class Artist with Painter, Sculptor {}
void main() {
Artist artist = Artist();
artist.paint();
artist.sculpt();
}
18. Mixin Example with Teacher and Researcher
mixin Teacher {
void teach() {
print("Teaching");
}
}
mixin Researcher {
void research() {
print("Researching");
}
}
class Professor with Teacher, Researcher {}
void main() {
Professor professor = Professor();
professor.teach();
professor.research();
}
19. Mixin Example with Gamer and Coder
mixin Gamer {
void play() {
print("Playing games");
}
}
mixin Coder {
void code() {
print("Coding");
}
}
class GameDeveloper with Gamer, Coder {}
void main() {
GameDeveloper dev = GameDeveloper();
dev.play();
dev.code();
}
20. Mixin Example with Singer and Dancer
mixin Singer {
void sing() {
print("Singing");
}
}
mixin Dancer {
void dance() {
print("Dancing");
}
}
class Performer with Singer, Dancer {}
void main() {
Performer performer = Performer();
performer.sing();
performer.dance();
}