# Object-Oriented Programming Concepts in Dart and Flutter ## 1. Abstraction Abstraction is the process of hiding complex implementation details and showing only the essential features of an object. ### Key Points: - Abstraction focuses on what an object does rather than how it does it. - In Dart, abstraction is achieved using abstract classes and interfaces. ### Example: ```dart // Abstract class abstract class Shape { double calculateArea(); double calculatePerimeter(); } // Concrete implementation class Circle extends Shape { double radius; Circle(this.radius); @override double calculateArea() { return 3.14 * radius * radius; } @override double calculatePerimeter() { return 2 * 3.14 * radius; } } // Usage Shape circle = Circle(5); print(circle.calculateArea()); // Output: 78.5 ``` In this example, `Shape` is an abstract class that defines a common interface for all shapes. The `Circle` class provides concrete implementations of the abstract methods. ## 2. Encapsulation Encapsulation is the bundling of data and the methods that operate on that data within a single unit (class). It restricts direct access to some of an object's components. ### Key Points: - In Dart, encapsulation is achieved using private variables and methods. - Private members are denoted by prefixing an underscore (_) to the identifier. ### Example: ```dart class BankAccount { String _accountNumber; double _balance; BankAccount(this._accountNumber, this._balance); double getBalance() { return _balance; } void deposit(double amount) { if (amount > 0) { _balance += amount; } } bool withdraw(double amount) { if (amount > 0 && _balance >= amount) { _balance -= amount; return true; } return false; } } // Usage var account = BankAccount('123456', 1000); account.deposit(500); print(account.getBalance()); // Output: 1500 ``` In this example, `_accountNumber` and `_balance` are private variables. They can only be accessed and modified through public methods like `getBalance()`, `deposit()`, and `withdraw()`. ## 3. Inheritance Inheritance is a mechanism where a new class is derived from an existing class, inheriting its properties and methods. ### Key Points: - Dart supports single inheritance, where a class can only inherit from one superclass. - The `extends` keyword is used to create a child class. - The `super` keyword is used to refer to the parent class. ### Example: ```dart class Animal { void breathe() { print('Breathing...'); } } class Mammal extends Animal { void walk() { print('Walking...'); } } class Dog extends Mammal { void bark() { print('Woof!'); } } // Usage var dog = Dog(); dog.breathe(); // Inherited from Animal dog.walk(); // Inherited from Mammal dog.bark(); // Dog's own method ``` In this example, `Dog` inherits from `Mammal`, which in turn inherits from `Animal`. This creates a hierarchy where `Dog` has access to all methods from its parent classes. ## 4. Polymorphism Polymorphism allows objects of different classes to be treated as objects of a common superclass. It enables a single interface to represent different underlying forms (data types). ### Key Points: - In Dart, polymorphism is achieved through method overriding and interfaces. - The `@override` annotation is used to indicate that a method is intended to override a superclass method. ### Example: ```dart abstract class Shape { double calculateArea(); } class Rectangle extends Shape { double width; double height; Rectangle(this.width, this.height); @override double calculateArea() { return width * height; } } class Circle extends Shape { double radius; Circle(this.radius); @override double calculateArea() { return 3.14 * radius * radius; } } // Usage void printArea(Shape shape) { print('Area: ${shape.calculateArea()}'); } var rectangle = Rectangle(5, 3); var circle = Circle(2); printArea(rectangle); // Output: Area: 15.0 printArea(circle); // Output: Area: 12.56 ``` In this example, both `Rectangle` and `Circle` are treated as `Shape` objects. The `printArea()` function demonstrates polymorphism by working with any `Shape` object, regardless of its specific type. ## Conclusion Understanding these four pillars of object-oriented programming is crucial for effective Dart and Flutter development. They provide a solid foundation for creating modular, maintainable, and scalable applications. Practice implementing these concepts in your projects to reinforce your understanding and improve your coding skills.