Menu
CoddyTech

Kế thừa cơ bản

Thuộc phần Lập trình hướng đối tượng trong hành trình Dart của Coddy. Bài học 36 trên 110.

Kế thừa cho phép một lớp có được các thuộc tính và phương thức của một lớp khác. Thay vì viết lại cùng một đoạn code, bạn tạo một lớp mới dựa trên lớp hiện có. Lớp ban đầu được gọi là lớp cha (hay lớp cha), còn lớp mới là lớp con (hay lớp con).

Trong Dart, bạn dùng từ khóa extends để kế thừa từ một lớp cha:

class Animal {
  String name;
  
  Animal(this.name);
  
  void eat() {
    print('$name is eating');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name);
  
  void bark() {
    print('$name says woof!');
  }
}

void main() {
  var dog = Dog('Buddy');
  dog.eat();   // Kế thừa từ Animal
  dog.bark();  // Định nghĩa trong Dog
}

Lớp Dog tự động có quyền truy cập vào thuộc tính name và phương thức eat() từ Animal, đồng thời có phương thức bark() riêng. Điều này tạo nên mối quan hệ “là một”: Dog là một Animal.

Lớp con có thể thêm thuộc tính và phương thức mới, nhưng kế thừa mọi thành phần công khai từ lớp cha. Lưu ý rằng các thành phần riêng tư (những thành phần có _) không thể được truy cập trực tiếp trong các lớp con thuộc thư viện khác, dù chúng vẫn tồn tại trong đối tượng được kế thừa.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống phương tiện để minh họa cách tính kế thừa cho phép các lớp con dùng lại và mở rộng chức năng của lớp cha. Bạn sẽ tạo một lớp cha dành cho các phương tiện nói chung và một lớp con dành cho một loại phương tiện cụ thể.

Bạn sẽ sắp xếp code thành hai tệp:

  • vehicle.dart: Định nghĩa các lớp tại đây:
    • Một lớp Vehicle (lớp cha) có thuộc tính String brand, hàm khởi tạo nhận thương hiệu và phương thức start() in ra [brand] engine starting...
    • Một lớp Motorcycle kế thừa Vehicle. Lớp này cần có thêm thuộc tính int cc (dung tích động cơ), hàm khởi tạo nhận cả thương hiệu và cc (truyền thương hiệu cho lớp cha bằng super), cùng phương thức riêng wheelie() in ra [brand] is doing a wheelie!
  • main.dart: Nhập tệp phương tiện và minh họa kế thừa trong thực tế:
    • Tạo một Vehicle có thương hiệu 'Toyota'
    • Gọi phương thức start() của đối tượng này
    • Tạo một Motorcycle có thương hiệu 'Harley' và cc là 1200
    • Gọi phương thức start() của xe máy (được kế thừa từ Vehicle)
    • Gọi phương thức wheelie() của xe máy (được định nghĩa trong Motorcycle)
    • In ra Motorcycle engine: [cc]cc để hiển thị thuộc tính riêng của lớp con

Hãy chú ý cách lớp Motorcycle tự động có thể truy cập thuộc tính brand và phương thức start() từ Vehicle, đồng thời có thuộc tính cc và phương thức wheelie() riêng. Đây là sức mạnh của tính kế thừa, xây dựng dựa trên code hiện có.

Đầu ra mong đợi:

Toyota engine starting...
Harley engine starting...
Harley is doing a wheelie!
Motorcycle engine: 1200cc

Tự làm thử

import 'vehicle.dart';

void main() {
  // TODO: Tạo một Vehicle có thương hiệu 'Toyota'
  
  // TODO: Gọi phương thức (method) start() của vehicle
  
  // TODO: Tạo một Motorcycle có thương hiệu 'Harley' và cc là 1200
  
  // TODO: Gọi phương thức start() của motorcycle (kế thừa từ Vehicle)
  
  // TODO: Gọi phương thức wheelie() của motorcycle
  
  // TODO: In ra 'Motorcycle engine: [cc]cc' bằng thuộc tính (property) cc của motorcycle
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Dart online