Inheritance
## Learning Objectives
- Understand class inheritance
- Work with abstract classes
- Master interfaces
- Learn mixins
## Inheritance Basics
### Extending a Class
```dart
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void bark() {
print('$name says Woof!');
}
}
void main() {
var dog = Dog('Buddy');
dog.eat(); // Buddy is eating
dog.bark(); // Buddy says Woof!
}
```
### The super Keyword
```dart
class Vehicle {
String brand;
Vehicle(this.brand);
void drive() {
print('Driving $brand');
}
}
class Car extends Vehicle {
int doors;
Car(String brand, this.doors) : super(brand);
@override
void drive() {
super.drive();
print('Car with $doors doors');
}
}
void main() {
var car = Car('Toyota', 4);
car.drive();
// Driving Toyota
// Car with 4 doors
}
```
## Abstract Classes
### Defining Abstract Class
```dart
abstract class Shape {
// Abstract method - no implementation
double area();
// Concrete method
void describe() {
print('Shape with area: ${area()}');
}
}
class Circle extends Shape {
double radius;
Circle(this.radius);
@override
double area() => 3.14159 * radius * radius;
}
class Rectangle extends Shape {
double width;
double height;
Rectangle(this.width, this.height);
@override
double area() => width * height;
}
void main() {
var circle = Circle(5);
circle.describe(); // Shape with area: 78.53975
var rect = Rectangle(4, 6);
rect.describe(); // Shape with area: 24
}
```
### Cannot Instantiate Abstract
```dart
abstract class Shape {
double area();
}
// var shape = Shape(); // Error: cannot instantiate abstract class
```
## Interfaces
### Implicit Interface
```dart
// Every class implicitly defines an interface
class Person {
String name;
Person(this.name);
void greet() {
print('Hello, I am $name');
}
}
// Implements interface
class Student implements Person {
@override
String name;
Student(this.name);
@override
void greet() {
print('Hi, I am $name and I study');
}
}
void main() {
var student = Student('Alice');
student.greet(); // Hi, I am Alice and I study
}
```
### Explicit Interface
```dart
class Reader {
void read() {
print('Reading...');
}
}
class Writer {
void write() {
print('Writing...');
}
}
// Can implement multiple
class Author implements Reader, Writer {
@override
void read() {
print('Author reading...');
}
@override
void write() {
print('Author writing...');
}
}
void main() {
var author = Author();
author.read();
author.write();
}
```
## Mixins
### Basic Mixin
```dart
mixin Flyable {
void fly() {
print('Flying!');
}
}
mixin Walkable {
void walk() {
print('Walking!');
}
}
class Bird with Flyable, Walkable {
String name;
Bird(this.name);
}
void main() {
var bird = Bird('Sparrow');
bird.fly(); // Flying!
bird.walk(); // Walking!
}
```
### Mixin with Constraints
```dart
mixin Navigator on Vehicle {
void navigate() {
print('Navigating...');
}
}
class Vehicle {
String brand = 'Generic';
}
// Can only mix into Vehicle or subclasses
class Car extends Vehicle with Navigator {
}
void main() {
var car = Car();
car.navigate();
}
```
### Mixin with Default Implementation
```dart
mixin PrintMixin {
void printData() {
print('Data: ${getData()}');
}
String getData(); // Required method
}
class MyClass with PrintMixin {
@override
String getData() => 'Hello from MyClass';
}
void main() {
var obj = MyClass();
obj.printData(); // Data: Hello from MyClass
}
```
## Mixin vs Extension
| Feature | Mixin | Extension |
|---------|-------|-----------|
| Adds fields | Yes | No |
| Adds constructors | Yes | No |
| Adds methods | Yes | Yes |
| Requires class definition | No | No |
| Multiple mixins | Yes | Single |
## Class Hierarchy
### Combining All
```dart
abstract class Animal {
String name;
Animal(this.name);
void breathe() {
print('$name is breathing');
}
}
abstract class Mammal extends Animal {
Mammal(super.name);
void walk() {
print('$name is walking');
}
}
mixin Flyable {
void fly() {
print('Flying');
}
}
class Bat extends Mammal with Flyable {
Bat(super.name);
}
void main() {
var bat = Bat('Bruce');
bat.breathe(); // Bruce is breathing
bat.walk(); // Bruce is walking
bat.fly(); // Flying
}
```
## Method Overriding
### @override Annotation
```dart
class Parent {
void greet() {
print('Hello from Parent');
}
}
class Child extends Parent {
@override
void greet() {
print('Hello from Child');
}
}
void main() {
var child = Child();
child.greet(); // Hello from Child
}
```
### super in Overridden Methods
```dart
class Parent {
String greet() => 'Hello';
}
class Child extends Parent {
@override
String greet() {
return '${super.greet()} from Child';
}
}
void main() {
print(Child().greet()); // Hello from Child
}
```
## Abstract vs Interface
| Aspect | Abstract | Interface |
|--------|----------|-----------|
| Methods | Abstract or concrete | Abstract only (before Dart 3) |
| Fields | Can have | Cannot have instance fields |
| Constructors | Can have | Cannot have |
| Multiple | Single extends | Multiple implements |
| Inheritance | Single extends | Multiple implements |
## Summary
- Inheritance: `class Child extends Parent`
- `super` refers to parent class
- Abstract classes: `abstract class` with abstract methods
- Interfaces: `implements` keyword, multiple allowed
- Mixins: `with` keyword, add functionality to classes
- `mixin M on T` restricts mixin to T or subclasses
- `@override` indicates method overriding
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →