Days 7-8: Advanced OOP

Days 7-8: Advanced OOP

Objective:

  • Learn inheritance, polymorphism, abstraction, and encapsulation.

  • Practice by creating small projects based on OOP concepts.


1. Inheritance

Inheritance allows a class to inherit properties and methods from another class.

// Parent class
class Animal {
  String name;

  Animal(this.name);

  void eat() {
    print('$name is eating');
  }
}

// Child class
class Dog extends Animal {
  Dog(String name) : super(name);

  void bark() {
    print('$name is barking');
  }
}

void main() {
  Dog dog = Dog('Buddy');
  dog.eat();  // Inherited method
  dog.bark(); // Child class method
}

Explanation:

  • Animal is the parent class with a property name and a method eat.

  • Dog is the child class that extends Animal and inherits its properties and methods.

  • The Dog class also has its own method bark.

Diagram:

  • Figure 1: Inheritance in Dart.


2. Polymorphism

Polymorphism allows objects to be treated as instances of their parent class rather than their actual class.

class Animal {
  void sound() {
    print('Animal makes a sound');
  }
}

class Dog extends Animal {
  @override
  void sound() {
    print('Dog barks');
  }
}

class Cat extends Animal {
  @override
  void sound() {
    print('Cat meows');
  }
}

void main() {
  Animal myDog = Dog();
  Animal myCat = Cat();

  myDog.sound(); // Dog barks
  myCat.sound(); // Cat meows
}

Explanation:

  • The Animal class has a method sound.

  • The Dog and Cat classes override the sound method.

  • Polymorphism allows calling the sound method on Animal references, which results in calling the overridden methods in Dog and Cat.

Diagram:

  • Figure 2: Polymorphism in Dart.


3. Abstraction

Abstraction allows defining methods without implementing them, using abstract classes and methods.

abstract class Shape {
  void draw(); // Abstract method
}

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

class Rectangle extends Shape {
  @override
  void draw() {
    print('Drawing a rectangle');
  }
}

void main() {
  Shape circle = Circle();
  Shape rectangle = Rectangle();

  circle.draw(); // Drawing a circle
  rectangle.draw(); // Drawing a rectangle
}

Explanation:

  • Shape is an abstract class with an abstract method draw.

  • Circle and Rectangle classes extend Shape and implement the draw method.

  • Abstract classes cannot be instantiated, but they can be used as reference types.

Diagram:

  • Figure 3: Abstraction in Dart.

    Abstraction Diagram


4. Encapsulation

Encapsulation restricts access to certain properties and methods using access modifiers.

class BankAccount {
  String _accountNumber; // Private property
  double _balance;       // Private property

  BankAccount(this._accountNumber, this._balance);

  // Getter for account number
  String get accountNumber => _accountNumber;

  // Getter for balance
  double get balance => _balance;

  // Method to deposit money
  void deposit(double amount) {
    if (amount > 0) {
      _balance += amount;
    }
  }

  // Method to withdraw money
  void withdraw(double amount) {
    if (amount > 0 && amount <= _balance) {
      _balance -= amount;
    }
  }
}

void main() {
  BankAccount account = BankAccount('123456', 1000.0);

  account.deposit(500.0);
  print('Balance: ${account.balance}'); // Balance: 1500.0

  account.withdraw(200.0);
  print('Balance: ${account.balance}'); // Balance: 1300.0
}

Explanation:

  • The BankAccount class encapsulates the properties _accountNumber and _balance by making them private.

  • Public getters provide read-only access to the properties.

  • Methods deposit and withdraw allow controlled modification of the balance.

Diagram:

  • Figure 4: Encapsulation in Dart.

    Encapsulation Diagram


5. Small Project: Library Management System

Project Objective:

  • Create a simple library management system using advanced OOP concepts.

Project Requirements:

  • Define a Book class with properties like title, author, and ISBN.

  • Define a Member class with properties like name, member ID, and a list of borrowed books.

  • Define a Library class with methods to add books, register members, lend books, and return books.

Code Implementation:

class Book {
  String title;
  String author;
  String isbn;

  Book(this.title, this.author, this.isbn);
}

class Member {
  String name;
  String memberId;
  List<Book> borrowedBooks = [];

  Member(this.name, this.memberId);

  void borrowBook(Book book) {
    borrowedBooks.add(book);
  }

  void returnBook(Book book) {
    borrowedBooks.remove(book);
  }
}

class Library {
  List<Book> books = [];
  List<Member> members = [];

  void addBook(Book book) {
    books.add(book);
  }

  void registerMember(Member member) {
    members.add(member);
  }

  void lendBook(String isbn, String memberId) {
    Book? book = books.firstWhere((book) => book.isbn == isbn, orElse: () => null);
    Member? member = members.firstWhere((member) => member.memberId == memberId, orElse: () => null);

    if (book != null && member != null) {
      member.borrowBook(book);
      books.remove(book);
      print('${member.name} borrowed ${book.title}');
    } else {
      print('Book or Member not found');
    }
  }

  void returnBook(String isbn, String memberId) {
    Member? member = members.firstWhere((member) => member.memberId == memberId, orElse: () => null);

    if (member != null) {
      Book? book = member.borrowedBooks.firstWhere((book) => book.isbn == isbn, orElse: () => null);
      if (book != null) {
        member.returnBook(book);
        books.add(book);
        print('${member.name} returned ${book.title}');
      } else {
        print('Book not found in borrowed books');
      }
    } else {
      print('Member not found');
    }
  }
}

void main() {
  // Create library instance
  Library library = Library();

  // Add books to library
  library.addBook(Book('Dart Programming', 'John Doe', '123'));
  library.addBook(Book('Flutter Development', 'Jane Smith', '456'));

  // Register members
  library.registerMember(Member('Alice', '001'));
  library.registerMember(Member('Bob', '002'));

  // Lend and return books
  library.lendBook('123', '001');
  library.returnBook('123', '001');
}

Explanation:

  • The Book class represents a book with properties title, author, and isbn.

  • The Member class represents a library member with properties name, memberId, and a list of borrowed books. It has methods to borrow and return books.

  • The Library class manages the collection of books and members. It has methods to add books, register members, lend books, and return books.

  • The main function demonstrates adding books to the library, registering members, lending books, and returning books.

Diagram:

  • Figure 5: Class Diagram for Library Management System.

    Class Diagram

By practicing these advanced OOP concepts, you will gain a deeper understanding of how to structure and organize your Dart programs effectively. Happy coding!