[Dart] Tổng quan về hướng đối tượng OOP
Lập trình hướng đối tượng (Object-Oriented Programming – OOP) là một trong những đặc trưng chính của ngôn ngữ Dart. Trong OOP, chúng ta làm việc với các đối tượng (objects) và lớp (classes) để tổ chức và quản lý mã nguồn một cách hiệu quả.
1. Các khái niệm cơ bản trong OOP Dart
Class (Lớp)
Lớp là một mẫu (blueprint) để tạo ra các đối tượng. Nó bao gồm các thuộc tính (properties) và phương thức (methods).
class Animal {
String name; // Thuộc tính
int age;
// Constructor
Animal(this.name, this.age);
// Method
void displayInfo() {
print('Name: $name, Age: $age');
}
}
Dart2. Object (Đối tượng)
void main() {
Animal dog = Animal('Dog', 2);
dog.displayInfo(); // Output: Name: Dog, Age: 2
}
DartEncapsulation (Đóng gói)
class BankAccount {
String _accountNumber; // Private variable
double _balance = 0;
BankAccount(this._accountNumber);
// Getter
double get balance => _balance;
// Method to deposit money
void deposit(double amount) {
_balance += amount;
}
// Method to withdraw money
void withdraw(double amount) {
if (amount <= _balance) {
_balance -= amount;
} else {
print('Insufficient balance');
}
}
}
DartInheritance (Kế thừa)
class Animal {
void eat() {
print('Animal is eating');
}
}
class Dog extends Animal {
void bark() {
print('Dog is barking');
}
}
void main() {
Dog dog = Dog();
dog.eat(); // Output: Animal is eating
dog.bark(); // Output: Dog is barking
}
DartPolymorphism (Đa hình)
Đa hình cho phép một phương thức có thể hoạt động khác nhau trên các lớp con.
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 animal;
animal = Dog();
animal.sound(); // Output: Dog barks
animal = Cat();
animal.sound(); // Output: Cat meows
}
Dart2. Các kiến thức nâng cao về OOP trong Dart
Abstract Class (Lớp trừu tượng)
Lớp trừu tượng được khai báo với từ khóa abstract
và không thể được khởi tạo trực tiếp. Nó dùng để định nghĩa các phương thức mà lớp con phải triển khai.
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 shape = Circle();
shape.draw(); // Output: Drawing a circle
}
DartInterface (Giao diện)
Dart không có từ khóa interface
nhưng bạn có thể sử dụng bất kỳ lớp nào như một giao diện.
class Printer {
void printData() {
print('Printing data...');
}
}
class Scanner {
void scanData() {
print('Scanning data...');
}
}
class AllInOnePrinter implements Printer, Scanner {
@override
void printData() {
print('All-in-one printer: Printing data...');
}
@override
void scanData() {
print('All-in-one printer: Scanning data...');
}
}
void main() {
AllInOnePrinter printer = AllInOnePrinter();
printer.printData();
printer.scanData();
}
DartMixin
Mixin cho phép thêm tính năng vào lớp mà không cần kế thừa.
mixin Swimming {
void swim() {
print('Swimming...');
}
}
class Fish with Swimming {}
void main() {
Fish fish = Fish();
fish.swim(); // Output: Swimming...
}
DartGetter và Setter
Dart hỗ trợ getter và setter để kiểm soát việc truy cập thuộc tính.
class Student {
String _name;
// Getter
String get name => _name;
// Setter
set name(String name) {
_name = name;
}
}
void main() {
Student student = Student();
student.name = 'John Doe'; // Using setter
print(student.name); // Using getter
}
Dart3. Case Study thực tế
Quản lý nhân sự (Employee Management System)
- Mô tả: Xây dựng hệ thống quản lý nhân viên sử dụng OOP.
- Các yêu cầu:
- Có các loại nhân viên: Nhân viên chính thức (FullTimeEmployee), Nhân viên hợp đồng (ContractEmployee).
- Mỗi nhân viên có các thông tin như: tên, ID, và phương thức tính lương khác nhau.
- Hệ thống phải có khả năng hiển thị thông tin và tính tổng lương.
Code mẫu:
abstract class Employee {
String name;
int id;
Employee(this.name, this.id);
double calculateSalary(); // Abstract method
void displayInfo() {
print('Name: $name, ID: $id');
}
}
class FullTimeEmployee extends Employee {
double basicSalary;
FullTimeEmployee(String name, int id, this.basicSalary) : super(name, id);
@override
double calculateSalary() {
return basicSalary + (basicSalary * 0.2); // Thêm 20% phụ cấp
}
}
class ContractEmployee extends Employee {
double hourlyRate;
int hoursWorked;
ContractEmployee(String name, int id, this.hourlyRate, this.hoursWorked)
: super(name, id);
@override
double calculateSalary() {
return hourlyRate * hoursWorked;
}
}
void main() {
Employee fullTime = FullTimeEmployee('Alice', 1, 3000);
Employee contract = ContractEmployee('Bob', 2, 20, 120);
fullTime.displayInfo();
print('Salary: ${fullTime.calculateSalary()}'); // Output: Salary: 3600.0
contract.displayInfo();
print('Salary: ${contract.calculateSalary()}'); // Output: Salary: 2400.0
}
DartPhân tích:
- Sử dụng lớp trừu tượng
Employee
để định nghĩa các thuộc tính và phương thức cơ bản. - Sử dụng tính kế thừa để tạo các lớp
FullTimeEmployee
vàContractEmployee
với logic tính lương riêng. - Hiển thị thông tin và tính tổng lương bằng cách tận dụng tính đa hình.