Lớp mở và lớp con
Thuộc phần Lập trình hướng đối tượng trong hành trình Kotlin của Coddy. Bài học 17 trên 57.
Kế thừa cho phép một lớp xây dựng dựa trên lớp khác. Lớp con có tất cả thuộc tính và phương thức của lớp cha, đồng thời có thể thêm thuộc tính và phương thức riêng. Theo mặc định, các lớp trong Kotlin không thể được kế thừa, vì vậy bạn cần đánh dấu một lớp bằng open trước khi lớp khác có thể kế thừa lớp đó:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name) {
fun fetch() = "$name fetches the ball"
}Bên trong main:
val rex = Dog("Rex")
println(rex.describe())
println(rex.fetch())Đầu ra:
Rex is an animal
Rex fetches the ballclass Dog(name: String) : Animal(name) cho biết Dog kế thừa Animal và truyền name cho hàm khởi tạo của lớp cha. Tham số này không có val, vì thuộc tính đã tồn tại trong Animal. Không thể kế thừa một lớp không có open:
class Plant(val name: String)
// class Tree(name: String) : Plant(name) // lỗi: kiểu này là final nên không thể kế thừa
open class Vehicle(val wheels: Int)
class Bike : Vehicle(2) // truyền một giá trị cố định
class Truck(val load: Int) : Vehicle(6) // thêm thuộc tính riêngDog là một Animal, vì vậy bạn có thể dùng một đối tượng của lớp con ở bất cứ nơi nào cần kiểu của lớp cha. Một List<Animal> có thể chứa chó, mèo và động vật thông thường, mỗi phần tử đều có các thành viên của Animal:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name)
class Cat(name: String, val indoor: Boolean) : Animal(name)Bên trong main:
val pets: List<Animal> = listOf(Dog("Rex"), Cat("Tom", true), Animal("Generic"))
for (p in pets) println(p.describe())Đầu ra:
Rex is an animal
Tom is an animal
Generic is an animalKế thừa mô hình hóa quan hệ là một: chó là động vật, tài khoản tiết kiệm là tài khoản. Khi một lớp chỉ sử dụng lớp khác (xe hơi có động cơ), hãy thêm một thuộc tính có kiểu đó. Trong Kotlin, các lớp mặc định bị đóng, vì vậy lớp nào cần cho phép mở rộng phải khai báo điều đó bằng open, còn các lớp khác giữ hành vi an toàn trước lớp con.
open class Account(val owner: String)
class SavingsAccount(owner: String) : Account(owner) // là một loại: kế thừa
class Engine(val horsepower: Int)
class Car(val engine: Engine) // có một: thuộc tínhThử thách
DễManager lặp lại những gì Employee đã có. Hãy mở lớp Employee và biến Manager thành lớp con của nó: Manager(name: String, salary: Int) truyền cả hai giá trị cho Employee và chỉ giữ lại những gì mới, một danh sách tên nhân viên báo cáo riêng tư cùng với addReport(name) và teamSize(). Trong Employee, raise(percent) tăng lương theo tỷ lệ phần trăm đó, làm tròn xuống, còn describe() trả về Ada earns 5500.
Code được cung cấp tạo một quản lý viên từ dòng đầu tiên (name,salary), thêm từng tên ở các dòng tiếp theo làm nhân viên báo cáo, tăng lương 10% và in ra Ada earns 5500 and leads 2, sau đó kiểm tra xem một quản lý viên có phải là Employee hay không.
Code của bạn nằm trong Employee.kt và Manager.kt. Main.kt chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
fun main() {
// Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
val input = generateSequence(::readLine).toList()
val (name, salary) = input[0].split(",")
val boss = Manager(name, salary.toInt())
for (report in input.drop(1)) boss.addReport(report)
boss.raise(10)
println("${boss.describe()} and leads ${boss.teamSize()}")
println("a manager is an employee: ${(boss as Any) is Employee}")
}
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ớpHàm khởi tạo chínhKhối init và kiểm tra tính hợp lệHàm khởi tạo phụÔn tập: thẻ thư viện4Kế thừa
Lớp mở và lớp conGhi đè thành viênsuper và hàm khởi tạoLớp trừu tượngÔn tập: Danh bạ nhân viên2Thuộc tính và tính đóng gói
Trình truy cập tùy chỉnhBộ sửa đổi phạm vi truy cậpSetter riêng tưlazy và lateinitÔn tập: tài khoản ngân hàng5Giao diện
Khai báo giao diệnPhương thức mặc địnhNhiều giao diệnGiao diện như kiểu dữ liệuÔn tập: Phương thức thanh toánTự luyện tập: Playground Kotlin