Parent and Child Classes in Dart – Detailed Notes with Practical Examples
Parent and child classes are fundamental concepts of Object-Oriented Programming (OOP) in Dart.
A parent class contains common properties and methods, while a child class can inherit those members and add
its own functionality.
JustAcademy's Flutter curriculum includes Dart OOP concepts such as classes, objects, constructors, inheritance,
polymorphism, and abstraction as part of its Dart Programming Fundamentals module.
Explore JustAcademy's Flutter Training
.
:contentReference[oaicite:0]{index=0}
1. What is a Parent Class?
A parent class is a class that provides properties and methods that can be inherited by another
class. It is also called a superclass or base class.
For example:
class Animal {
String name = 'Animal';
void eat() {
print('$name is eating');
}
}
In this example, Animal is the parent class. It contains a property called name and a
method called eat().
2. What is a Child Class?
A child class is a class that inherits from a parent class. It is also called a
subclass or derived class.
Dart uses the extends keyword to create an inheritance relationship.
class Animal {
void eat() {
print('Animal is eating');
}
}
class Dog extends Animal {
void bark() {
print('Dog is barking');
}
}
Here:
Animal is the parent class.
Dog is the child class.
Dog inherits the eat() method from Animal.
Dog also has its own bark() method.
3. Parent and Child Class Relationship
Animal
|
| extends
v
Dog
The relationship can be described as:
Dog is an Animal.
This type of relationship is commonly called an "is-a" relationship.
4. Basic Parent and Child Class Example
class Person {
String name = 'Amit';
void introduce() {
print('My name is $name');
}
}
class Student extends Person {
void study() {
print('$name is studying');
}
}
void main() {
Student student = Student();
student.introduce();
student.study();
}
Output:
My name is Amit
Amit is studying
The Student object can call both:
introduce() – inherited from Person
study() – defined inside Student
5. Parent Class Properties
A child class can use inherited properties that are accessible to it.
class Vehicle {
String brand = 'Toyota';
int year = 2025;
}
class Car extends Vehicle {
void displayCar() {
print('Brand: $brand');
print('Year: $year');
}
}
void main() {
Car car = Car();
car.displayCar();
}
Output:
Brand: Toyota
Year: 2025
6. Parent Class Methods
A child class can use methods inherited from the parent class.
class Vehicle {
void start() {
print('Vehicle started');
}
void stop() {
print('Vehicle stopped');
}
}
class Car extends Vehicle {
void drive() {
print('Car is driving');
}
}
void main() {
Car car = Car();
car.start();
car.drive();
car.stop();
}
Output:
Vehicle started
Car is driving
Vehicle stopped
7. Child Class Can Add Its Own Members
Inheritance does not restrict a child class to the functionality of the parent. A child can define additional
properties and methods.
class Employee {
String name = 'Rahul';
void work() {
print('$name is working');
}
}
class Developer extends Employee {
String language = 'Dart';
void writeCode() {
print('$name is writing $language code');
}
}
void main() {
Developer developer = Developer();
developer.work();
developer.writeCode();
}
Output:
Rahul is working
Rahul is writing Dart code
8. Parent Constructor and Child Constructor
When the parent class has a constructor that requires values, the child class can pass values to the parent
constructor using super.
class Person {
String name;
int age;
Person(this.name, this.age);
}
class Student extends Person {
String course;
Student(
String name,
int age,
this.course,
) : super(name, age);
void display() {
print('Name: $name');
print('Age: $age');
print('Course: $course');
}
}
void main() {
Student student =
Student('Neha', 21, 'Flutter');
student.display();
}
Output:
Name: Neha
Age: 21
Course: Flutter
9. Understanding super
The super keyword refers to the parent class. It can be used to:
- Call a parent constructor.
- Call a parent method.
- Access an inherited member when needed.
Calling a Parent Method
class Animal {
void sound() {
print('Animal makes a sound');
}
}
class Dog extends Animal {
@override
void sound() {
super.sound();
print('Dog barks');
}
}
void main() {
Dog dog = Dog();
dog.sound();
}
Output:
Animal makes a sound
Dog barks
10. Method Overriding
Sometimes a child class needs to provide a different implementation of a method inherited from the parent.
This is called method overriding.
class Animal {
void sound() {
print('Animal makes a sound');
}
}
class Dog extends Animal {
@override
void sound() {
print('Dog barks');
}
}
void main() {
Dog dog = Dog();
dog.sound();
}
Output:
Dog barks
The @override annotation indicates that the child class is replacing the inherited implementation
of sound().
11. Parent and Child Classes with Different Behaviors
A common use of inheritance is to define a general behavior in a parent class and specialize it in child classes.
class Animal {
void sound() {
print('Animal makes a sound');
}
}
class Dog extends Animal {
@override
void sound() {
print('Dog says: Woof');
}
}
class Cat extends Animal {
@override
void sound() {
print('Cat says: Meow');
}
}
class Cow extends Animal {
@override
void sound() {
print('Cow says: Moo');
}
}
void main() {
Dog dog = Dog();
Cat cat = Cat();
Cow cow = Cow();
dog.sound();
cat.sound();
cow.sound();
}
Output:
Dog says: Woof
Cat says: Meow
Cow says: Moo
12. Parent Reference and Child Object
Dart supports polymorphism, so a variable whose static type is the parent class can refer to an object of a child
class.
class Animal {
void sound() {
print('Animal sound');
}
}
class Dog extends Animal {
@override
void sound() {
print('Dog barks');
}
}
void main() {
Animal animal = Dog();
animal.sound();
}
Output:
Dog barks
The variable is declared as Animal, but the actual object is a Dog. The overridden
method in Dog is executed.
13. Practical Example: Person and Student
A student is a person, so common information can be placed in the parent class.
class Person {
String name;
int age;
Person(this.name, this.age);
void displayPerson() {
print('Name: $name');
print('Age: $age');
}
}
class Student extends Person {
int rollNumber;
String course;
Student(
String name,
int age,
this.rollNumber,
this.course,
) : super(name, age);
void displayStudent() {
displayPerson();
print('Roll Number: $rollNumber');
print('Course: $course');
}
}
void main() {
Student student =
Student('Aman', 20, 101, 'Flutter');
student.displayStudent();
}
Output:
Name: Aman
Age: 20
Roll Number: 101
Course: Flutter
14. Practical Example: Employee and Developer
class Employee {
String name;
double salary;
Employee(this.name, this.salary);
void displayEmployee() {
print('Employee: $name');
print('Salary: ₹$salary');
}
}
class Developer extends Employee {
String programmingLanguage;
Developer(
String name,
double salary,
this.programmingLanguage,
) : super(name, salary);
void develop() {
print('$name is developing using $programmingLanguage');
}
}
void main() {
Developer developer =
Developer('Ravi', 60000, 'Dart');
developer.displayEmployee();
developer.develop();
}
Output:
Employee: Ravi
Salary: ₹60000.0
Ravi is developing using Dart
15. Practical Example: Vehicle and Car
class Vehicle {
String brand;
int speed;
Vehicle(this.brand, this.speed);
void displayVehicle() {
print('Brand: $brand');
print('Speed: $speed km/h');
}
void start() {
print('$brand has started');
}
}
class Car extends Vehicle {
int doors;
Car(
String brand,
int speed,
this.doors,
) : super(brand, speed);
void displayCar() {
displayVehicle();
print('Doors: $doors');
}
}
void main() {
Car car = Car('Honda', 180, 4);
car.start();
car.displayCar();
}
Output:
Honda has started
Brand: Honda
Speed: 180 km/h
Doors: 4
16. Practical Example: Bank Account
class BankAccount {
String accountHolder;
double balance;
BankAccount(this.accountHolder, this.balance);
void deposit(double amount) {
balance += amount;
print('Deposited: ₹$amount');
}
void showBalance() {
print('Balance: ₹$balance');
}
}
class SavingsAccount extends BankAccount {
double interestRate;
SavingsAccount(
String accountHolder,
double balance,
this.interestRate,
) : super(accountHolder, balance);
void addInterest() {
double interest =
balance * interestRate / 100;
balance += interest;
print('Interest added: ₹$interest');
}
}
void main() {
SavingsAccount account =
SavingsAccount('Priya', 10000, 5);
account.deposit(2000);
account.addInterest();
account.showBalance();
}
Here, SavingsAccount inherits the common banking functionality from BankAccount and
adds its own interest-related behavior.
17. Practical Example: Product and Electronics Product
In an e-commerce application, many products share common properties such as name and price. Specialized products
can inherit these properties.
class Product {
String name;
double price;
Product(this.name, this.price);
void displayProduct() {
print('Product: $name');
print('Price: ₹$price');
}
}
class ElectronicsProduct extends Product {
int warrantyYears;
ElectronicsProduct(
String name,
double price,
this.warrantyYears,
) : super(name, price);
void displayWarranty() {
print('Warranty: $warrantyYears years');
}
}
void main() {
ElectronicsProduct laptop =
ElectronicsProduct('Laptop', 65000, 2);
laptop.displayProduct();
laptop.displayWarranty();
}
Output:
Product: Laptop
Price: ₹65000.0
Warranty: 2 years
18. Practical Example: User and Admin
A common application design is to have a general User class and a specialized Admin
child class.
class User {
String username;
String email;
User(this.username, this.email);
void login() {
print('$username logged in');
}
void displayProfile() {
print('Username: $username');
print('Email: $email');
}
}
class Admin extends User {
List<String> permissions;
Admin(
String username,
String email,
this.permissions,
) : super(username, email);
void showPermissions() {
print('Permissions: $permissions');
}
void deleteUser() {
print('Admin can delete users');
}
}
void main() {
Admin admin = Admin(
'admin01',
'[email protected]',
['create', 'edit', 'delete'],
);
admin.login();
admin.displayProfile();
admin.showPermissions();
admin.deleteUser();
}
19. Practical Example: Shape Hierarchy
class Shape {
void draw() {
print('Drawing shape');
}
}
class Circle extends Shape {
double radius;
Circle(this.radius);
double area() {
return 3.14 * radius * radius;
}
}
class Rectangle extends Shape {
double width;
double height;
Rectangle(this.width, this.height);
double area() {
return width * height;
}
}
void main() {
Circle circle = Circle(5);
Rectangle rectangle = Rectangle(10, 5);
circle.draw();
print('Circle area: ${circle.area()}');
rectangle.draw();
print('Rectangle area: ${rectangle.area()}');
}
20. Parent and Child Classes in Flutter
Understanding parent and child classes is particularly useful in Flutter because Flutter applications use a large
hierarchy of classes and widgets. JustAcademy's Flutter curriculum includes Dart OOP followed by Flutter Widgets
and UI Design, including concepts such as StatelessWidget and StatefulWidget. :contentReference[oaicite:1]{index=1}
Example with StatelessWidget
import 'package:flutter/material.dart';
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(
child: Text(
'Welcome to Flutter',
),
),
);
}
}
In this example, WelcomeScreen is a child class of StatelessWidget.
The build() method is overridden to define the widget's UI.
21. Parent Class and Child Class in Flutter Widgets
class MyScreen extends StatelessWidget {
const MyScreen({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(
child: Text('My Screen'),
),
);
}
}
The important concepts are:
StatelessWidget is the parent class being extended.
MyScreen is the child class.
extends establishes the inheritance relationship.
@override indicates that build() is being overridden.
super.key passes the key to the parent constructor.
22. Multilevel Parent and Child Classes
Multiple levels of inheritance can be created when a child class becomes a parent for another class.
class Animal {
void eat() {
print('Eating');
}
}
class Mammal extends Animal {
void breathe() {
print('Breathing');
}
}
class Dog extends Mammal {
void bark() {
print('Barking');
}
}
void main() {
Dog dog = Dog();
dog.eat();
dog.breathe();
dog.bark();
}
The structure is:
Animal
|
v
Mammal
|
v
Dog
23. Multiple Child Classes from One Parent
Several child classes can inherit from the same parent class.
class Employee {
void work() {
print('Employee is working');
}
}
class Developer extends Employee {
void code() {
print('Developer is coding');
}
}
class Designer extends Employee {
void design() {
print('Designer is designing');
}
}
void main() {
Developer developer = Developer();
Designer designer = Designer();
developer.work();
developer.code();
designer.work();
designer.design();
}
The structure is:
Employee
/ \
/ \
Developer Designer
24. Parent vs Child Class
Feature |
Parent Class |
Child Class |
|---|
Purpose |
Provides common functionality. |
Reuses and extends parent functionality. |
Other Name |
Superclass / Base class |
Subclass / Derived class |
Inheritance |
Can be inherited by another class. |
Inherits from another class. |
New Features |
Defines common features. |
Can add specialized features. |
Method Overriding |
Provides original implementation. |
Can override inherited methods. |
super |
Not normally needed to access itself. |
Used to access parent functionality. |
25. Parent Class vs Child Class Example
class Animal {
// Parent class
void eat() {
print('Eating');
}
}
class Dog extends Animal {
// Child class
void bark() {
print('Barking');
}
}
Code |
Belongs To |
|---|
eat() |
Parent class |
bark() |
Child class |
extends Animal |
Creates inheritance |
Dog() |
Creates child object |
26. Advantages of Parent and Child Classes
- Code Reusability: Common code can be written once in the parent class.
- Less Duplication: Child classes can reuse existing methods and properties.
- Easy Maintenance: Shared functionality can be maintained centrally.
- Extensibility: Child classes can add specialized behavior.
- Polymorphism: Parent types can represent objects of child classes.
- Better Organization: Related classes can be grouped into meaningful hierarchies.
- Flutter Understanding: It helps developers understand framework class relationships and widget inheritance.
27. When Should You Use Parent and Child Classes?
Inheritance is useful when there is a meaningful "is-a" relationship.
Good examples include:
- Dog is an Animal.
- Car is a Vehicle.
- Student is a Person.
- Developer is an Employee.
- Admin is a User.
- ElectronicsProduct is a Product.
28. Inheritance vs Composition
Not every relationship should use inheritance. If one object contains another object, composition is often a more
natural representation.
Inheritance – "Is-a"
class Vehicle {}
class Car extends Vehicle {}
A car is a vehicle.
Composition – "Has-a"
class Engine {
void start() {
print('Engine started');
}
}
class Car {
Engine engine = Engine();
void startCar() {
engine.start();
}
}
A car has an engine.
29. Common Mistakes
Mistake 1: Forgetting extends
Incorrect:
class Dog {
}
Correct:
class Dog extends Animal {
}
Mistake 2: Forgetting the Parent Constructor
class Person {
String name;
Person(this.name);
}
class Student extends Person {
Student(String name) : super(name);
}
Mistake 3: Incorrect Method Override
When overriding a method, the child implementation should be compatible with the inherited member's contract.
Using @override helps Dart's analyzer identify certain errors.
Mistake 4: Using Inheritance Only for Small Code Reuse
Inheritance creates a relationship between classes. If there is no meaningful "is-a" relationship, consider
composition or another design approach.
30. Best Practices
- Keep parent classes focused on genuinely shared behavior.
- Use
extends only when the inheritance relationship makes conceptual sense.
- Use
@override when overriding inherited methods.
- Use
super when you need parent behavior or constructor initialization.
- Avoid unnecessarily deep inheritance hierarchies.
- Prefer composition when the relationship is "has-a" rather than "is-a".
- Use inheritance together with polymorphism when specialized child behavior is required.
- Keep child classes focused on their specialized responsibilities.
31. Quick Revision Program
class Person {
String name;
Person(this.name);
void introduce() {
print('Hello, I am $name');
}
}
class Student extends Person {
String course;
Student(
String name,
this.course,
) : super(name);
@override
void introduce() {
super.introduce();
print('I am studying $course');
}
}
void main() {
Student student =
Student('Rahul', 'Flutter');
student.introduce();
}
Output:
Hello, I am Rahul
I am studying Flutter
32. Important Keywords
Keyword / Concept |
Purpose |
Example |
|---|
extends |
Creates an inheritance relationship. |
class Dog extends Animal |
super |
References the parent class. |
super.sound() |
@override |
Indicates an overridden inherited member. |
@override void sound() |
Parent Class |
Provides common functionality. |
Animal |
Child Class |
Inherits and extends functionality. |
Dog |
Polymorphism |
Allows child objects to be handled through parent types. |
Animal animal = Dog() |
33. Practice Exercises
- Create a
Person parent class and a Student child class.
- Create an
Animal parent class with Dog, Cat, and Cow child classes.
- Override the
sound() method in each child class.
- Create an
Employee parent class and Developer and Designer child classes.
- Use a parent constructor and pass values using
super.
- Use
super to call a parent method from a child class.
- Create a
Product parent class and ElectronicsProduct child class.
- Create a
User parent class and Admin child class.
- Create a Flutter
StatelessWidget and identify its parent class and overridden method.
- Create a multilevel inheritance example using
Animal, Mammal, and Dog.
34. Key Takeaways
- A parent class provides common properties and methods.
- A child class inherits from the parent class.
- Dart uses the
extends keyword for class inheritance.
- A child class can use inherited properties and methods.
- A child class can add its own properties and methods.
- A child class can override inherited methods.
@override is used to identify an overridden member.
super is used to access parent functionality and constructors.
- Parent constructors are initialized before the child constructor body.
- Parent and child classes are commonly used to implement polymorphism.
- Inheritance generally represents an "is-a" relationship.
- Composition generally represents a "has-a" relationship.
- Understanding parent and child classes is useful when working with Dart OOP and Flutter widgets.
35. Learn Flutter with JustAcademy
JustAcademy's Flutter training covers Dart Programming Fundamentals, including OOP, classes, objects,
constructors, inheritance, polymorphism, and abstraction, followed by Flutter widgets and UI development.
:contentReference[oaicite:2]{index=2}
View JustAcademy Flutter Training
Register for JustAcademy Course Demo