Dart is an object-oriented programming language that offers strong support for OOP principles like encapsulation, inheritance, polymorphism, and abstraction. This guide will cover these four pillars and additional advanced topics such as getters and setters, static methods, and operator overloading.
For further information on other topics of Dart, click here.
Introduction to OOP in Dart
Object-Oriented Programming (OOP) is a paradigm that organizes code using objects and classes. Dart, being an OOP language, provides a structured way to build applications using these principles, making your code modular and reusable.
Classes and Objects
A class is a blueprint for creating objects, and an object is an instance of a class. Classes in Dart define properties (fields) and methods (functions).
Example of a Class and Object
class Car {
String brand;
int year;
Car(this.brand, this.year);
void displayInfo() {
print('Brand: $brand, Year: $year');
}
}
void main() {
Car myCar = Car('Toyota', 2021);
myCar.displayInfo(); // Output: Brand: Toyota, Year: 2021
}
For more details on classes and objects, see our detailed article.
Constructors
Constructors are special methods that initialize objects. Dart supports default, named, and factory constructors.
Example of a Named Constructor
class Student {
String name;
int age;
Student.named(this.name, this.age);
void showInfo() {
print('Name: $name, Age: $age');
}
}
void main() {
Student student = Student.named('Alice', 20);
student.showInfo(); // Output: Name: Alice, Age: 20
}
For more on constructors, see our detailed article.
Four Pillars of OOP in Dart
The four pillars of Object-Oriented Programming are fundamental concepts that support the structure and behavior of OOP languages like Dart.
1. Encapsulation
Encapsulation involves bundling data (variables) and methods that operate on that data within a single unit (class) and restricting access to some components.
class BankAccount {
double _balance; // Private variable
BankAccount(this._balance);
void deposit(double amount) {
_balance += amount;
}
double get balance => _balance; // Getter for balance
}
void main() {
BankAccount account = BankAccount(1000);
account.deposit(500);
print('Balance: ${account.balance}'); // Output: Balance: 1500
}
See our detailed article on encapsulation for more.
2. Inheritance
Inheritance allows a class to inherit properties and methods from another class, promoting code reuse.
class Animal {
void sound() {
print('Some generic animal sound');
}
}
class Dog extends Animal {
@override
void sound() {
print('Bark');
}
}
void main() {
Dog dog = Dog();
dog.sound(); // Output: Bark
}
Learn more about inheritance in our detailed article.
3. Polymorphism
Polymorphism allows objects to be treated as instances of their parent class. This provides flexibility in code and enhances reusability.
class Shape {
void draw() {
print('Drawing shape');
}
}
class Circle extends Shape {
@override
void draw() {
print('Drawing circle');
}
}
void main() {
Shape shape = Circle();
shape.draw(); // Output: Drawing circle
}
For more examples, see our detailed article on polymorphism.
4. Abstraction
Abstraction hides complex implementation details and shows only the necessary features of an object.
abstract class Vehicle {
void start(); // Abstract method
}
class Car extends Vehicle {
@override
void start() {
print('Car is starting...');
}
}
void main() {
Car car = Car();
car.start(); // Output: Car is starting...
}
Learn more about abstraction in our detailed article.
Getters and Setters
Getters and Setters provide access to private properties while maintaining encapsulation.
Example of Getters and Setters
class Rectangle {
double _width, _height;
Rectangle(this._width, this._height);
double get area => _width * _height; // Getter
set width(double value) => _width = value; // Setter
}
void main() {
Rectangle rect = Rectangle(5, 10);
print('Area: ${rect.area}'); // Output: Area: 50
rect.width = 8; // Using setter
print('New Area: ${rect.area}'); // Output: New Area: 80
}
For more on getters and setters, see our detailed article.
Static Methods and Variables
Static members belong to the class itself rather than to any specific object. They can be called without creating an instance of the class.
Example of Static Methods
class Calculator {
static int add(int a, int b) => a + b; // Static method
}
void main() {
print('Sum: ${Calculator.add(5, 3)}'); // Output: Sum: 8
}
For more about static methods and variables, check our detailed article.
Operator Overloading
Operator overloading allows you to redefine the behavior of operators for user-defined classes.
Example of Operator Overloading
class Complex {
double real, imaginary;
Complex(this.real, this.imaginary);
Complex operator +(Complex other) {
return Complex(real + other.real, imaginary + other.imaginary);
}
}
void main() {
Complex c1 = Complex(2, 3);
Complex c2 = Complex(4, 5);
Complex sum = c1 + c2;
print('Sum: ${sum.real} + ${sum.imaginary}i'); // Output: Sum: 6.0 + 8.0i
}
See our detailed article on operator overloading for more information.
Mixins
Mixins are a way of reusing a class’s code in multiple class hierarchies.
Example of Mixins
mixin CanFly {
void fly() {
print('Flying...');
}
}
class Bird with CanFly {}
void main() {
Bird bird = Bird();
bird.fly(); // Output: Flying...
}
For further details on mixins, check out our detailed article.
Conclusion
This guide provides a comprehensive overview of Object-Oriented Programming (OOP) in Dart, covering all major concepts including classes, objects, constructors, the four pillars of OOP (encapsulation, inheritance, polymorphism, and abstraction), getters and setters, static methods, operator overloading, and mixins. Mastering these concepts is essential for developing robust Dart applications. For a more in-depth understanding, be sure to read our detailed articles on each topic.
Happy Coding…!!!
Leave a Reply