Dart OOP

Dart OOP (Object-Oriented Programming) là cách lập trình dựa trên object (đối tượng) và class (lớp). Dart hỗ trợ đầy đủ các khái niệm OOP, giúp tổ chức code thành các đối tượng có dữ liệu (properties) và hành vi (methods), từ đó code dễ quản lý, tái sử dụng và mở rộng hơn.

OOP trong Dart chủ yếu gồm:

Basic OOP Concepts Explained with Code

  • Class & Object
  • Encapsulation (Đóng gói)
  • Inheritance (Kế thừa)
  • Polymorphism (Đa hình)
  • Abstraction (Trừu tượng)

Class và Object

Class là bản thiết kế (blueprint) dùng để định nghĩa cấu trúc và hành vi của một nhóm đối tượng.

Object là một thể hiện (instance) cụ thể được tạo ra từ class.

Class thường chứa:

  • Properties / Fields: dữ liệu hoặc trạng thái của object.
  • Methods: các hành vi mà object có thể thực hiện.
  • Constructor: dùng để khởi tạo object.

Code ví dụ

class User {
  String name;
  int age;

  User(this.name, this.age);

  void introduce() {
    print("Tôi là $name, $age tuổi");
  }
}

void main() {
  User user = User("Tien", 21);

  user.introduce();
}

Trong code trên:

  • User là class.
  • name và age là properties.
  • introduce() là method.
  • User(this.name, this.age) là constructor.
  • user là object được tạo từ class User.

Constructor

Constructor là phương thức đặc biệt được gọi khi một object được tạo ra. Constructor thường được dùng để khởi tạo giá trị ban đầu cho object.

Dart hỗ trợ nhiều loại constructor:

  • Generative Constructor: constructor thông thường.
  • Named Constructor: constructor có tên riêng.
  • Factory Constructor: constructor có thể kiểm soát cách object được tạo và trả về một instance.

Code ví dụ

class User {
  String name;
  int age;

  // Generative Constructor
  User(this.name, this.age);

  // Named Constructor
  User.guest()
      : name = "Guest",
        age = 0;
}

void main() {
  User user1 = User("Tien", 21);
  User user2 = User.guest();
}

Encapsulation – Đóng gói

Encapsulation là nguyên tắc giới hạn quyền truy cập trực tiếp vào dữ liệu bên trong object và kiểm soát cách dữ liệu được truy cập hoặc thay đổi.

Dart không có từ khóa private giống Java hoặc C#. Trong Dart, một thành phần bắt đầu bằng _ sẽ được coi là private trong library.

Code ví dụ

class BankAccount {
  double _balance = 0;

  double get balance => _balance;

  void deposit(double amount) {
    if (amount > 0) {
      _balance += amount;
    }
  }
}

void main() {
  final account = BankAccount();

  account.deposit(1000);

  print(account.balance);
}

Ở đây:

  • _balance được giới hạn truy cập trực tiếp bên ngoài library.
  • get balance cho phép đọc giá trị.
  • deposit() kiểm soát cách thay đổi _balance.

Encapsulation giúp tránh việc dữ liệu bên trong object bị thay đổi tùy ý.

Inheritance – Kế thừa

Inheritance cho phép một class con (subclass) kế thừa thuộc tính và phương thức từ class cha (superclass).

Dart sử dụng từ khóa extends để kế thừa class.

Code ví dụ

class Animal {
  void eat() {
    print("Animal is eating");
  }
}

class Dog extends Animal {
  void bark() {
    print("Dog is barking");
  }
}

void main() {
  final dog = Dog();

  dog.eat();
  dog.bark();
}

Dog kế thừa Animal, vì vậy object Dog có thể sử dụng method eat() của Animal.

Dart hỗ trợ single inheritance, nghĩa là một class chỉ có thể extends trực tiếp từ một class cha.

Override – Ghi đè phương thức

Override là khi class con định nghĩa lại một method đã tồn tại ở class cha để thay đổi cách hoạt động của method đó.

Dart sử dụng annotation @override để thể hiện rõ method đang được ghi đè.

Code ví dụ

class Animal {
  void sound() {
    print("Animal sound");
  }
}

class Dog extends Animal {
  @override
  void sound() {
    print("Woof");
  }
}

Dog vẫn kế thừa Animal, nhưng method sound() được thay đổi cách hoạt động.

Polymorphism – Đa hình

Polymorphism là khả năng một interface hoặc kiểu dữ liệu có thể đại diện cho nhiều object khác nhau, và mỗi object có thể thực hiện cùng một hành động theo cách khác nhau.

Đa hình thường xuất hiện khi sử dụng inheritance + method overriding.

Code ví dụ

class Animal {
  void sound() {
    print("Animal sound");
  }
}

class Dog extends Animal {
  @override
  void sound() {
    print("Woof");
  }
}

class Cat extends Animal {
  @override
  void sound() {
    print("Meow");
  }
}

void main() {
  List<Animal> animals = [
    Dog(),
    Cat(),
  ];

  for (final animal in animals) {
    animal.sound();
  }
}

Mặc dù animals có kiểu List<Animal>, mỗi object lại thực hiện sound() theo cách riêng.

Đây chính là runtime polymorphism.

Abstraction – Trừu tượng

Abstraction là việc chỉ thể hiện những gì cần thiết và ẩn đi các chi tiết triển khai bên trong.

Trong Dart, abstraction thường được thực hiện thông qua:

  • Abstract class
  • Abstract method
  • Interface

Một abstract class không thể được tạo object trực tiếp.

Code ví dụ

abstract class Animal {
  void sound();
}

class Dog extends Animal {
  @override
  void sound() {
    print("Woof");
  }
}

class Cat extends Animal {
  @override
  void sound() {
    print("Meow");
  }
}

Animal chỉ quy định rằng các class con phải có sound(), nhưng không quy định cách sound() hoạt động.

Dog và Cat tự triển khai method này theo cách riêng.

Interface trong Dart

Trong Dart, mọi class đều có thể được sử dụng như một interface.

Từ khóa implements cho phép một class thực hiện contract của class khác mà không kế thừa implementation của class đó.

Code ví dụ

class Animal {
  void sound() {
    print("Animal sound");
  }
}

class Dog implements Animal {
  @override
  void sound() {
    print("Woof");
  }
}

Khác với extends:

  • extends → kế thừa cả interface và implementation.
  • implements → chỉ lấy contract/interface, class con phải tự triển khai các thành phần cần thiết.

Mixin

Mixin là cơ chế cho phép tái sử dụng một nhóm hành vi cho nhiều class mà không cần sử dụng inheritance.

Dart sử dụng từ khóa mixin để khai báo mixin và with để sử dụng.

Code ví dụ

mixin Flyable {
  void fly() {
    print("Flying");
  }
}

class Bird with Flyable {}

class Plane with Flyable {}

void main() {
  Bird bird = Bird();
  Plane plane = Plane();

  bird.fly();
  plane.fly();
}

Mixin phù hợp khi nhiều class cần dùng chung một nhóm hành vi nhưng không có quan hệ cha – con.

Các từ khóa OOP quan trọng trong Dart

  • class: khai báo class.
  • new: tạo object, hiện nay thường có thể bỏ qua.
  • this: tham chiếu đến object hiện tại.
  • extends: kế thừa class.
  • implements: triển khai interface.
  • abstract: khai báo class hoặc method trừu tượng.
  • override: ghi đè method của class cha/interface.
  • mixin: khai báo mixin.
  • with: sử dụng mixin.
  • super: truy cập constructor hoặc thành phần của class cha.
  • static: thành phần thuộc về class thay vì từng object.
  • final: giá trị chỉ được gán một lần.
  • const: tạo giá trị compile-time constant.

Phân biệt các khái niệm OOP

  • Encapsulation → kiểm soát quyền truy cập dữ liệu.
  • Inheritance → tái sử dụng bằng quan hệ class cha – class con.
  • Polymorphism → cùng một interface nhưng có nhiều cách triển khai.
  • Abstraction → ẩn chi tiết triển khai, chỉ thể hiện phần cần thiết.
  • Mixin → tái sử dụng hành vi giữa nhiều class mà không cần inheritance.

Nói chung là:

  • Class = bản thiết kế của object.
  • Object = instance được tạo từ class.
  • Constructor = khởi tạo object.
  • Encapsulation = đóng gói và kiểm soát dữ liệu.
  • Inheritance = class con kế thừa class cha.
  • Polymorphism = một interface, nhiều cách triển khai.
  • Abstraction = ẩn chi tiết, chỉ thể hiện phần cần thiết.
  • Interface = contract mà class phải tuân theo.
  • Mixin = tái sử dụng hành vi giữa nhiều class.
  • extends = kế thừa implementation.
  • implements = triển khai interface.
  • with = sử dụng mixin.

Bài viết khác

Testing Principles & Testing Levels

Testing Principles & Testing Levels là gì? Trong kiểm thử phần mềm, Testing Principles (Các nguyên tắc kiểm thử) là kim chỉ nam giúp định hướng cách thực hiện kiểm thử hiệu quả, trong khi Testing Levels (Các cấp độ kiểm thử) là các giai đoạn phân loại phạm vi kiểm thử từ nhỏ đến […]

Future & Async/Await

Future & Async/Await là các cơ chế trong Dart dùng để xử lý bất đồng bộ (Asynchronous Programming), cho phép chương trình thực hiện những tác vụ cần thời gian như gọi API, đọc database, đọc file… mà không làm ứng dụng bị đứng trong lúc chờ kết quả. Future Future đại diện cho một […]

Null Safety

Null Safety là tính năng giúp ngăn chặn lỗi do các biến có giá trị rỗng (null) gây ra. Được áp dụng rộng rãi trong ngôn ngữ Dart (và framework Flutter), tính năng này giúp các nhà phát triển phát hiện lỗi ngay tại thời điểm biên dịch thay vì khi ứng dụng chạy, giúp […]

SOLID và Design pattern

SOLID SOLID là 5 nguyên tắc thiết kế phần mềm hướng đối tượng, giúp xây dựng hệ thống dễ hiểu, dễ thay đổi, dễ mở rộng, dễ test, ít gây ảnh hưởng dây chuyền, dễ bảo trì SOLID gồm: S: Single Responsibility Principle O: Open/Closed Principle L: Liskov Substitution Principle I: Interface Segregation Principle D: […]

SDLC&STLC

1. Tổng quan nền tảng về quy trình phát triển và kiểm thử phần mềm Trong bất kỳ một dự án công nghệ thông tin nào, dù là ứng dụng di động nhỏ hay hệ thống phần mềm doanh nghiệp khổng lồ, việc để sản phẩm đi đến thành công không thể dựa vào sự […]

Frontend Web Roadmap

  Roadmap download here frontend web   Keyword Git Agile Waterfall Scrum Kanban SOLID Internet Fundamentals HTTP/HTTPS DNS & Domain Browser Fundamentals HTML Semantic HTML Forms & Validation CSS Flexbox & Grid Responsive Web Design Bootstrap JavaScript Fundamentals DOM Async JavaScript Fetch / HTTP Client TypeScript npm / pnpm / yarn React Components React Component […]

Leave a Reply

Your email address will not be published. Required fields are marked *