Hàm khởi tạo phụ
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 5 trên 57.
Một lớp có thể cung cấp thêm cách tạo đối tượng bằng hàm khởi tạo phụ, được khai báo bằng constructor. Mỗi hàm phải gọi hàm khởi tạo chính bằng this(...):
class Temperature(val celsius: Double) {
constructor(fahrenheit: Int) : this((fahrenheit - 32) * 5 / 9.0)
}Bên trong main:
println(Temperature(20.0).celsius)
println(Temperature(212).celsius)Đầu ra:
20.0
100.0Đối số mặc định thường khiến hàm khởi tạo phụ trở nên không cần thiết. Hãy ưu tiên một hàm khởi tạo chính với các giá trị mặc định, và dùng hàm khởi tạo phụ khi đầu vào có hình dạng khác, chẳng hạn như văn bản cần phân tích:
class Color(val r: Int, val g: Int, val b: Int) {
constructor(gray: Int) : this(gray, gray, gray)
constructor(hex: String) : this(hex.substring(0, 2).toInt(16), hex.substring(2, 4).toInt(16), hex.substring(4, 6).toInt(16))
fun label() = "rgb($r, $g, $b)"
}Bên trong main:
println(Color(128).label())
println(Color("FF8000").label())Đầu ra:
rgb(128, 128, 128)
rgb(255, 128, 0)Hàm khởi tạo chính và các khối init của nó chạy trước, sau đó đến phần thân của hàm khởi tạo phụ:
class Log(val name: String) {
init { println("primary: $name") }
constructor(id: Int) : this("log-$id") {
println("secondary: $id")
}
}Bên trong main:
Log(7)Đầu ra:
primary: log-7
secondary: 7Các hàm khởi tạo phải hoạt động với mọi phiên bản nạp chồng một cách rõ ràng. Không được có hai hàm khởi tạo cùng kiểu tham số, và lời gọi có thể khớp với nhiều hàm khởi tạo sẽ không biên dịch.
class Size(val w: Int, val h: Int) {
constructor(side: Int) : this(side, side) // Size(3) -> hình vuông
// constructor(w: Int) : this(w, 1) // lỗi: trùng chữ ký với hàm khởi tạo ở trên
}Thử thách
DễHoàn thiện lớp Duration(val seconds: Int) với hàm khởi tạo phụ (minutes: Int, seconds: Int) và một hàm khác nhận văn bản như 1:30 hoặc 2:05:10 (giờ:phút:giây). Thêm format(), hàm này trả về h:mm:ss với phút và giây có hai chữ số.
Code được cung cấp đọc các khoảng thời lượng dưới dạng văn bản có một hoặc hai dấu hai chấm, tạo từng khoảng thời lượng bằng hàm khởi tạo nhận văn bản rồi in ra format(), sau đó in ra total và tổng đã định dạng.
Viết code trong Duration.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()
var total = 0
for (line in input) {
val d = Duration(line)
println(d.format())
total += d.seconds
}
println("total " + Duration(total).format())
}
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