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.
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 sendervàString content. Thêm hàm khởi tạo nhận cả hai giá trị và phương thứcdisplay()để in raFrom [sender]: [content] - Một lớp
UrgentMessagekế thừaMessage. Lớp này cần có thêm thuộc tínhString 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ằngsuper. Ghi đè phương thứcdisplay()để gọi phiên bản của lớp cha bằngsuper.display()trước, sau đó in raPriority: [priority]ở dòng tiếp theo
- Một lớp
main.dart: Nhập tệp tin nhắn và minh họa cáchsuperhoạt động trong cả hàm khởi tạo lẫn phương thức:- Tạo một
Messagethô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
UrgentMessagetừ'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ó
- Tạo một
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: HIGHTự 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
}
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
1Nền tảng về lập trình hướng đối tượng
Tệp bên ngoàiThư viện và câu lệnh importGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcBiến thể hiệnKiến thức cơ bản về hàm khởi tạoÔn tập: Máy tính đơn giản4An toàn với giá trị null
Giới thiệu về an toàn với giá trị nullCó thể null và không thể nullToán tử ? và !Từ khóa late và an toàn với giá trị nullToán tử xử lý nullAn toàn với giá trị null trong lớpÔn tập: hệ thống hồ sơ người dùng7Lớp trừu tượng và interface
Lớp trừu tượngPhương thức trừu tượngInterface trong DartInterface ngầm địnhTriển khai và kế thừaNhiều interfaceÔn tập: Máy tính hình10Bộ sưu tập và kiểu tổng quát
Tổng quan về List, Set và MapBộ sưu tập an toàn về kiểuLớp tổng quátPhương thức tổng quátRàng buộc kiểu tổng quátIterable và IteratorÔn tập: Lưu trữ tổng quát2Hàm khởi tạo trong Dart
Hàm khởi tạo mặc địnhHàm khởi tạo có tênDanh sách khởi tạoHàm khởi tạo hằng sốHàm khởi tạo nhà máyHàm khởi tạo chuyển hướngÔn tập: Trình tạo hình dạng5Đóng gói
Thành viên công khai và riêng tưQuy ước tiền tố _Tính riêng tư ở cấp thư việnTìm hiểu sâu về getter và setterChe giấu thông tinÔn tập: hồ sơ học sinh8Mixin
Giới thiệu về MixinTạo MixinSử dụng nhiều MixinTừ khóa on trong MixinMixin và kế thừaMixin và giao diệnÔn tập: hệ thống động vật3Thuộc tính của lớp
Thành viên instance và thành viên tĩnhTrường final và constBiến latePhương thức và trường tĩnhGetter và setterÔn tập: trình quản lý tài khoản ngân hàng6Kế thừa
Kế thừa cơ bảnTừ khóa superGhi đè phương thứcChú thích @overrideTừ khóa lớp finalHàm khởi tạo và kế thừaÔn tập: phân cấp nhân viên9Đa hình
Khái niệm cơ bản về đa hìnhĐa hình qua giao diệnKiểm tra kiểu lúc chạyToán tử is và asTừ khóa hiệp biếnÔn tập: Bộ xử lý thanh toánTự luyện tập: Trình biên dịch Dart online