Lớp con
Thuộc phần Lập trình hướng đối tượng trong hành trình Swift của Coddy. Bài học 22 trên 57.
Tính kế thừa cho phép một lớp xây dựng dựa trên một lớp khác. class Dog: Animal tạo Dog thành một lớp con của lớp cha Animal: chó có mọi thuộc tính và phương thức của động vật, cùng với những gì Dog bổ sung:
class Animal {
var name: String
init(name: String) { self.name = name }
func describe() -> String { "\(name) is an animal" }
}
class Dog: Animal {
func fetch() -> String { "\(name) fetches the ball" }
}
let rex = Dog(name: "Rex")
print(rex.describe())
print(rex.fetch())Đầu ra:
Rex is an animal
Rex fetches the ballLớp con không thêm thuộc tính được lưu trữ nào sẽ kế thừa các hàm khởi tạo của lớp cha, đó là lý do Dog(name:) hoạt động mà không cần init trong Dog. Kế thừa mô hình hóa mối quan hệ is-a: mọi chú chó đều là động vật, vì vậy bạn có thể dùng Dog ở bất cứ nơi nào cần Animal:
class Animal {
var name: String
init(name: String) { self.name = name }
}
class Cat: Animal {}
class Dog: Animal {}
let pets: [Animal] = [Cat(name: "Tom"), Dog(name: "Rex")]
for pet in pets { print(pet.name) }Đầu ra:
Tom
RexChỉ lớp mới hỗ trợ kế thừa; struct và enum không thể kế thừa. Một lớp có nhiều nhất một lớp cha, nhưng một lớp cha có thể có nhiều lớp con, tạo thành một hệ thống phân cấp:
class Vehicle { var wheels = 0 }
class Car: Vehicle { } // Car là một Vehicle
class Bike: Vehicle { } // Bike là một Vehicle
// struct Truck: Vehicle { } // lỗi: cấu trúc không thể kế thừaĐặt những gì mọi lớp con cùng có vào lớp cha, còn những điểm khác biệt thì chỉ đặt trong từng lớp con. Khi một kiểu không thực sự là một dạng của kiểu kia, kế thừa không phải công cụ phù hợp; một thuộc tính chứa kiểu còn lại thường phù hợp hơn.
class Shape {
var name: String
init(name: String) { self.name = name }
func label() -> String { "a \(name)" }
}
class Square: Shape {
var side = 1.0
func area() -> Double { side * side }
}
let s = Square(name: "square")
s.side = 3
print(s.label())
print(s.area())Đầu ra:
a square
9.0Thử thách
DễEmployee lưu trữ name và salary, đồng thời có phương thức raise(by:) tăng lương theo một tỷ lệ phần trăm (làm tròn xuống). Hãy khai báo lớp con Manager, bổ sung thuộc tính được lưu trữ reports (mảng tên, ban đầu để trống), phương thức addReport(_:) và phương thức teamSize() trả về số lượng báo cáo.
Code được cung cấp tạo một quản lý từ dòng đầu tiên (name,salary), thêm mỗi tên ở các dòng tiếp theo làm báo cáo, tăng lương 10% và in ra Ada earns 5500 and leads 2.
Code của bạn nằm trong Employee.swift và Manager.swift. main.swift chứa code đầu vào/đầu ra được cung cấp và không thể chỉnh sửa.
Tự làm thử
// Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
var input: [String] = []
while let line = readLine() { input.append(line) }
let head = input[0].split(separator: ",").map(String.init)
let boss = Manager(name: head[0], salary: Int(head[1])!)
for name in input.dropFirst() { boss.addReport(name) }
boss.raise(by: 10)
print("\(boss.name) earns \(boss.salary) and leads \(boss.teamSize())")
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
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpPhương thức và selfHàm khởi tạoLớp là tham chiếuÔn tập: Thẻ thư viện2Struct và kiểu giá trị
StructNgữ nghĩa giá trịPhương thức thay đổiStruct hay classÔn tập: mặt hàng trong kho5Kế thừa
Lớp conGhi đè phương thứcHàm khởi tạo và superfinal và hệ phân cấpÔn tập: hệ phân cấp nhân viên8Các giao thức tiêu chuẩn
CustomStringConvertibleEquatableComparableHashableÔn tập: Sắp xếp tùy chỉnhTự luyện tập: Playground Swift