How Object-oriented programming (OOP) in Flutter using Dart

Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code that operates on that data. The objects are instances of classes, which are essentially user-defined data types that encapsulate data and functions (methods) that operate on that data.

OOP provides a way to organize code and data in a more intuitive and reusable manner, making it easier to maintain and modify software over time. The principles of OOP include encapsulation, abstraction, inheritance, and polymorphism. These principles enable OOP to achieve modularity, extensibility, and maintainability.

OOP in flutter


Here's an example of OOP in Flutter using Dart, the programming language used in Flutter development:

class Car {
  String make;
  String model;
  int year;
  int speed = 0;

  Car(this.make, this.model, this.year);

  void accelerate() {
    speed += 30;
  }

  void brake() {
    speed -= 30;
  }

  void displaySpeed() {
    print('Current speed: $speed');
  }
}

void main() {
  Car myCar = Car('Fiat', 'Honda', 2020);

  myCar.accelerate();
  myCar.displaySpeed(); // Current speed: 10

  myCar.brake();
  myCar.displaySpeed(); // Current speed: 0
}

The principles of object-oriented programming (OOP) in Flutter include:

  • Abstraction
  • Inheritance
  • Polymorphism
  • Encapsulation
  • Classes and Objects
These principles can be applied in Flutter by using classes and objects in Dart, the programming language used in Flutter development.

Abstraction: 

Hiding the implementation details and exposing only relevant information to the user.

Example:

abstract class Shape {
  void draw();
}

class Circle extends Shape {
  void draw() {
    print('Drawing a Circle');
  }
}

class Square extends Shape {
  void draw() {
    print('Drawing a Square');
  }
}

void main() {
  Shape circle = Circle();
  Shape square = Square();

  circle.draw(); // Drawing a Circle
  square.draw(); // Drawing a Square
}

In this example, we have an abstract class Shape with a single method draw(). The Circle and Square classes both extend the Shape class and implement their own versions of the draw() method.

When we create instances of the Circle and Square classes, we can refer to them using a reference of type Shape, which allows us to treat them as objects of a common class. This is an example of abstraction in action, as we are only exposing the relevant information to the user (the draw() method), while hiding the implementation details.

Inheritance: 

Reusing existing code by inheriting properties and behaviour from a parent class.

Example:
class Animal {
  String name;
  int age;

  Animal(this.name, this.age);

  void makeSound() {
    print('Animal Sound');
  }
}

class Dog extends Animal {
  String breed;

  Dog(String name, int age, this.breed) : super(name, age);

  @override
  void makeSound() {
    print('Bark!');
  }
}

void main() {
  Dog myDog = Dog('Max', 5, 'Labrador');

  print(myDog.name); // Max
  print(myDog.age); // 5
  print(myDog.breed); // Labrador

  myDog.makeSound(); // Bark!
}

In this example, we have a base class Animal with two properties, name and age, and a method makeSound(). The Dog class extends the Animal class and adds a new property, breed. The Dog class also overrides the makeSound() method to provide its own implementation.

When we create an instance of the Dog class, it inherits the properties and behaviour from the Animal class, but can also add its own properties and override the behaviour as needed. This is an example of inheritance in action, as we are reusing existing code from the Animal class in the Dog class.

Polymorphism: 

Allowing objects of different classes to be treated as objects of a common class.

Example:

abstract class Shape {
  void draw();
}

class Circle extends Shape {
  void draw() {
    print('Drawing a Circle');
  }
}

class Square extends Shape {
  void draw() {
    print('Drawing a Square');
  }
}

void drawShapes(List<Shape> shapes) {
  for (Shape shape in shapes) {
    shape.draw();
  }
}

void main() {
  List<Shape> shapes = [Circle(), Square()];

  drawShapes(shapes);
  /*
  Output:
  Drawing a Circle
  Drawing a Square
  */
}

In this example, we have an abstract class Shape with a single method draw(). The Circle and Square classes both extend the Shape class and implement their own versions of the draw() method.

We also have a function drawShapes() that takes a list of Shape objects as an argument and calls the draw() method on each of them. Since the Circle and Square classes are subclasses of Shape, they can be passed as arguments to the drawShapes() function and their methods will be called dynamically at runtime based on the actual type of the objects.

This is an example of polymorphism in action, as the drawShapes() function can work with objects of different classes (Circle and Square) that share a common interface (the Shape class), without having to know the exact type of the objects it is working with.

Encapsulation: 

Wrapping data and functions within a single unit or object to protect it from outside access or modification.

Example:

class BankAccount {
  String _accountHolder;
  int _balance = 0;

  BankAccount(this._accountHolder);

  void deposit(int amount) {
    _balance += amount;
  }

  void withdraw(int amount) {
    _balance -= amount;
  }

  int getBalance() {
    return _balance;
  }
}

void main() {
  BankAccount account = BankAccount('John Doe');
  account.deposit(100);
  account.withdraw(50);

  print(account.getBalance()); // 50
}

In this example, we have a class BankAccount with three properties: _accountHolder, _balance, and a private field _balance that is initialized to 0. The class also has methods to deposit and withdraw funds, as well as a method to get the balance.

The private field _balance can only be accessed from within the class, which ensures that the balance can only be modified through the methods provided by the class. This is an example of encapsulation in action, as we are encapsulating the implementation details of the bank account (the balance) and exposing a public interface for interacting with the account (the deposit and withdrawal methods).

Classes and Objects: 

Implementing objects as instances of classes and defining their behaviour through member functions or methods.

Example:

class Car {
  String make;
  String model;
  int year;

  Car(this.make, this.model, this.year);

  void start() {
    print('Car started.');
  }
}

void main() {
  Car myCar = Car('Toyota', 'Camry', 2020);

  print(myCar.make); // Toyota
  print(myCar.model); // Camry
  print(myCar.year); // 2020

  myCar.start(); // Car started.
}

In this example, we have a class Car with three properties: make, model, and year. The class also has a method start() that prints a message to the console.

When we create an instance of the Car class (myCar), we pass in values for the properties, which are then stored in the object. We can access the properties and call the methods on the object, just like any other variable.

This is an example of using classes and objects in Dart. The class defines a blueprint for creating objects, and each object created from the class is an instance of that class and contains its own data and behaviour.

Comments

Popular posts from this blog

Error Handling in Flutter - Gradle issue

How to Make a Dynamic and Trending ListView with Flutter Widgets?

Understanding API integration with Getx State management