Menu
CoddyTech

Từ khóa super

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 37 trên 110.

Từ khóa super cho phép lớp con truy cập trực tiếp vào lớp cha. Bạn đã thấy từ khóa này trong hàm khởi tạo với super(name), nhưng nó cũng hữu ích trong những ngữ cảnh khác.

Khi cần gọi hàm khởi tạo của lớp cha, super truyền các đối số lên chuỗi kế thừa:

class Vehicle {
  String brand;
  int year;
  
  Vehicle(this.brand, this.year);
}

class Car extends Vehicle {
  int doors;
  
  Car(String brand, int year, this.doors) : super(brand, year);
}

Từ khóa super cũng cho phép bạn truy cập các phương thức và thuộc tính của lớp cha từ bên trong lớp con. Điều này đặc biệt hữu ích khi bạn muốn sử dụng hành vi của lớp cha cùng với hành vi của riêng mình:

class Animal {
  String name;
  
  Animal(this.name);
  
  void makeSound() {
    print('$name makes a sound');
  }
}

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void makeSound() {
    super.makeSound();  // Gọi phương thức (method) của lớp cha trước
    print('$name says meow!');
  }
}

Khi gọi super.makeSound(), bạn đang gọi rõ ràng phiên bản phương thức của lớp cha. Nếu không có super, gọi makeSound() sẽ tham chiếu đến phương thức của lớp hiện tại, có thể gây ra đệ quy vô hạn.

Hãy nghĩ về super như một cách nói “dùng phiên bản của lớp cha”, dù đó là hàm khởi tạo, phương thức hay thuộc tính.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống nhắn tin để minh họa cách từ khóa super cho phép các lớp con truy cập và mở rộng hành vi của lớp cha. Bạn sẽ tạo một hệ thống phân cấp, trong đó các loại tin nhắn khác nhau được xây dựng dựa trên một lớp tin nhắn cơ sở.

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

  • message.dart: Định nghĩa các lớp tin nhắn tại đây:
    • Một lớp Message (lớp cha) có String sender và String content. Thêm hàm khởi tạo nhận cả hai giá trị và phương thức display() để in ra From [sender]: [content]
    • Một lớp UrgentMessage kế thừa Message. Lớp này cần có thêm thuộc tính String priority. Hàm khởi tạo nhận sender, content và priority, rồi truyền hai giá trị đầu tiên cho lớp cha bằng super. Ghi đè phương thức display() để gọi phiên bản của lớp cha bằng super.display() trước, sau đó in ra Priority: [priority] ở dòng tiếp theo
  • main.dart: Nhập tệp tin nhắn và minh họa cách super hoạt động trong cả hàm khởi tạo lẫn phương thức:
    • Tạo một Message thông thường từ 'Alice' với nội dung 'Hello there!'
    • Gọi phương thức display() của nó
    • In ra một dòng trống để ngăn cách
    • Tạo một UrgentMessage từ 'Bob' với nội dung 'Server is down!' và mức độ ưu tiên 'HIGH'
    • Gọi phương thức display() của nó

Hãy chú ý cách UrgentMessage dùng super theo hai cách: trong hàm khởi tạo để truyền dữ liệu cho lớp cha, và trong phương thức được ghi đè để đưa đầu ra của lớp cha vào trước khi bổ sung phần riêng.

Đầu ra dự kiến:

From Alice: Hello there!

From Bob: Server is down!
Priority: HIGH

Tự làm thử

import 'message.dart';

void main() {
  // TODO: Tạo một Message thông thường từ 'Alice' với nội dung 'Hello there!'
  
  // TODO: Gọi phương thức display() của thông báo
  
  // TODO: In ra một dòng trống để phân cách
  
  // TODO: Tạo một UrgentMessage từ 'Bob' với nội dung 'Server is down!' và mức ưu tiên 'HIGH'
  
  // TODO: Gọi phương thức display() của thông báo khẩn cấp
}
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