Introduction to extends Vs with Vs implements in Dart Language
When working with object-oriented programming (OOP) in Dart, you will come across the keywords extends
, with
, and
rong>implements
. Each plays a crucial role in inheritance and code reuse. Understanding when and how to use these keywords effectively is essential for writing clean, maintainable, and reusable code in Dart. In this article, we’ll break down the differences between extends
, with
, and implements
, and explore their usage through examples.
Understanding Dart Inheritance
Before listing some of their differences, it is important to understand what inheritance is. Inheritance is the feature wherein one class can inherit properties and methods from another. This allows for code reusability and creates a hierarchy among classes.
Dart is an object-oriented language that supports only single inheritances. That means a class can inherit properties and behaviors from only one superclass. The introduction of mixins and interfaces is mainly to transcend this limit for more flexibility.
2. The extends
Keyword in Dart
Dart uses the keyword extends when one class is inheriting from another. It is also called as classical inheritance or subclassing. A subclass that extends a superclass gets all the methods and properties from its superclass and can override if it needs to.
Syntax for extends
class SuperClass {
void display() {
print('This is the superclass');
}
}
class SubClass extends SuperClass {
@override
void display() {
print('This is the subclass');
}
}
Here, the SubClass
extends SuperClass
, meaning it inherits the display
method from the superclass but overrides it with its own implementation.
Use Case for extends
The extends
keyword is typically used when you want to represent an “is-a” relationship between classes. For example, a Dog
class might extend an Animal
class, as a dog is a type of animal.
The with
Keyword in Dart (Mixins)
In Dart, the with
keyword is used to apply mixins to a class. A mixin is a way of sharing functionality between classes without establishing a parent-child relationship. A class can apply multiple mixins, enabling Dart to overcome the limitations of single inheritance.
Syntax for with
mixin Flyer {
void fly() {
print('Flying');
}
}
mixin Swimmer {
void swim() {
print('Swimming');
}
}
class Duck with Flyer, Swimmer {
void display() {
print('I am a Duck');
}
}
In this example, the Duck
class uses two mixins: Flyer
and Swimmer
. The with
keyword allows the Duck
class to inherit the behavior from both mixins without forming a strict inheritance hierarchy.
Use Case for with
The with
keyword is ideal for situations where you want to share functionality across multiple classes but don’t want to create a deep inheritance hierarchy. Mixins are particularly useful for code reuse, as they allow you to add behavior to classes in a flexible manner.
The implements
Keyword in Dart
The implements
keyword is used when a class wants to implement an interface. In Dart, every class can be treated as an interface. When a class implements an interface, it must provide concrete implementations of all the methods and properties defined in that interface.
Syntax for implements
class Animal {
void makeSound();
}
class Dog implements Animal {
@override
void makeSound() {
print('Bark');
}
}
In this example, the Dog
class implements the Animal
interface and provides a concrete implementation of the makeSound
method.
Use Case for implements
The implements
keyword is useful when you want to enforce that a class follows a particular structure. It ensures that the class provides implementations for all methods defined in the interface. This is particularly useful in scenarios where you are designing abstract classes or API-like structures.
Comparing extends
Vs with
Vs implements
Let’s summarize the key differences between extends
, with
, and implements
:
Feature | extends | with (Mixins) | implements |
---|---|---|---|
Relationship Type | Inheritance (is-a relationship) | Mixin (code sharing) | Interface implementation |
Number of Classes | Can extend only one class | Can apply multiple mixins | Can implement multiple interfaces |
Method Inheritance | Inherits methods, can override | Inherits methods from mixins | Must implement all methods |
Typical Use Case | When one class is a type of another | When sharing behavior across classes | When enforcing method signatures |
Combining extends
, with
, and implements
In Dart, you can combine extends
, with
, and implements
within a single class to take advantage of all three mechanisms.
Example
class Animal {
void makeSound() {
print('Animal sound');
}
}
mixin Flyer {
void fly() {
print('Flying');
}
}
class Bird extends Animal with Flyer implements Flyer {
@override
void makeSound() {
print('Chirp');
}
}
Here, the Bird
class:
- Extends the
Animal
class. - Uses the
Flyer
mixin to add flying capability. - Implements the
Flyer
interface to ensure the required methods are present.
Example of extends Vs with Vs implements in Dart Language
In Dart, extends
, with
, and implements
are used to create relationships between classes in different ways. Here’s an example showcasing the differences between them:
1. extends
– Inheritance
- A class can inherit from another class using
extends
. This allows the subclass to use the properties and methods of the parent class.
class Animal {
void move() {
print('The animal moves');
}
}
class Dog extends Animal {
void bark() {
print('The dog barks');
}
}
void main() {
Dog dog = Dog();
dog.move(); // Inherited from Animal
dog.bark(); // Defined in Dog
}
2. with
– Mixin
- A mixin is a class that other classes can use to borrow functionality. Using
with
, a class can include features from multiple mixins.
mixin Runner {
void run() {
print('Running fast!');
}
}
mixin Swimmer {
void swim() {
print('Swimming swiftly!');
}
}
class Athlete with Runner, Swimmer {}
void main() {
Athlete athlete = Athlete();
athlete.run(); // From Runner mixin
athlete.swim(); // From Swimmer mixin
}
3. implements
– Interface
- A class can implement an interface, which forces it to define all the methods of that interface.
abstract class Vehicle {
void start();
}
class Car implements Vehicle {
@override
void start() {
print('Car starts');
}
}
class Bike implements Vehicle {
@override
void start() {
print('Bike starts');
}
}
void main() {
Vehicle car = Car();
Vehicle bike = Bike();
car.start(); // Car implementation
bike.start(); // Bike implementation
}
extends
: Inherits from a base class (single inheritance).with
: Mixes in functionality from multiple mixins.implements
: Forces a class to implement methods from an interface (no inheritance of behavior, just structure).
Advantages of extends Vs with Vs implements in Dart Language
Advantages of extends
:
- Inheritance of Behavior: Allows a class to inherit properties and methods from a parent class, enabling code reuse and reducing redundancy.
- Method Overriding: Subclasses can override methods to provide specialized behavior while still accessing the original parent functionality.
- Simplified Structure: Establishes a clear hierarchical relationship, making it easier to understand and follow class relationships.
Advantages of with
(Mixin):
- Multiple Behavior Reuse: Enables the inclusion of multiple behaviors (from multiple mixins) without creating complex inheritance chains.
- Avoids Deep Inheritance: Mixins can add reusable functionality to any class without requiring direct inheritance, promoting code modularity.
- Combines Independent Features: Allows classes to borrow different functionalities, improving code flexibility and reusability.
Advantages of implements
:
- Enforces Structure: Forces a class to implement all methods and properties of the interface, ensuring consistency across different implementations.
- Custom Implementations: Allows classes to define their own behavior while adhering to a common contract, promoting flexibility.
- Multiple Interface Support: A class can implement multiple interfaces, allowing it to fit into various contexts without inheriting any concrete behavior.
Disadvantages of extends Vs with Vs implements in Dart Language
Disadvantages of extends
:
- Single Inheritance Limitation: Dart only allows single inheritance, meaning a class can only extend one parent class, limiting flexibility when multiple behaviors are needed.
- Tight Coupling: Inheritance creates a strong relationship between the parent and child classes, which can lead to rigid code structures that are harder to maintain or refactor.
- Inheritance of Unwanted Behavior: The child class inherits all non-private methods and properties from the parent class, which may include unwanted or unnecessary functionality.
Disadvantages of with
(Mixin):
- No State Initialization: Mixins cannot have constructors, so you cannot initialize state or enforce certain behaviors when the mixin is used.
- Potential for Conflicts: If multiple mixins define the same method or property, it can lead to method collisions, causing confusion or bugs.
- Less Clarity: Using several mixins can make the source of a class’s behavior less clear, making the code harder to read and maintain.
Disadvantages of implements
:
- Rigid Contracts: Implementing an interface enforces strict adherence to its contract, which may limit flexibility if changes need to be made across several classes.
- No Inherited Behavior: Unlike
extends
,implements
does not inherit any actual functionality, only the structure. This requires the class to implement all methods from the interface, even if the implementation is repetitive. - Verbose: When implementing multiple interfaces, the class can become verbose as you need to write full implementations for all required methods.
Discover more from PiEmbSysTech
Subscribe to get the latest posts sent to your email.