Lớp học lập trình này nằm trong khóa học về Kotlin dành cho lập trình viên. Bạn sẽ nhận được nhiều giá trị nhất từ khóa học này nếu bạn làm việc qua các lớp học lập trình theo trình tự. Tùy thuộc vào kiến thức của mình, bạn có thể đọc lướt một số phần. Khóa học này dành cho những lập trình viên biết ngôn ngữ hướng đối tượng và muốn học Kotlin.
Giới thiệu
Trong lớp học lập trình này, bạn đã tìm hiểu về các lớp, hàm và phương thức chung, cũng như cách chúng hoạt động trong Kotlin.
Thay vì xây dựng một ứng dụng mẫu duy nhất, các bài học trong khóa học này được thiết kế để trang bị cho bạn kiến thức nhưng hãy độc lập với nhau để có thể đọc lướt các phần mà bạn quen thuộc. Nhiều ví dụ sử dụng chủ đề thủy cung để liên kết chúng với nhau. Và nếu bạn muốn xem toàn bộ câu chuyện về thủy cung, hãy xem khóa học Kotlin Bootcamp dành cho lập trình viên Udacity.
Kiến thức bạn cần có
- Cú pháp của hàm, lớp và phương thức Kotlin
- Cách tạo lớp học mới trong IntelliJ IDEA và chạy chương trình
Kiến thức bạn sẽ học được
- Cách làm việc với các lớp, phương thức và hàm chung
Bạn sẽ thực hiện
- Tạo một lớp chung và thêm các hạn chế
- Tạo loại
in
vàout
- Tạo các hàm, phương thức và hàm mở rộng chung
Giới thiệu chung
Kotlin, giống như nhiều ngôn ngữ lập trình, có các loại chung. Kiểu chung cho phép bạn đặt một lớp chung, do đó làm cho một lớp linh hoạt hơn nhiều.
Giả sử bạn đang triển khai một lớp MyList
lưu giữ danh sách các mục. Nếu không có chung chung, bạn sẽ cần triển khai phiên bản MyList
mới cho từng loại: một cho Double
, một cho String
, một cho Fish
. Với mục chung, bạn có thể tạo danh sách chung chung để có thể lưu giữ mọi loại đối tượng. Điều này giống như việc tạo loại ký tự đại diện phù hợp với nhiều loại.
Để xác định một loại chung chung, hãy đặt T trong dấu ngoặc nhọn <T>
sau tên lớp. (Bạn có thể sử dụng một chữ cái khác hoặc tên dài hơn, nhưng quy ước về loại chung là T.)
class MyList<T> {
fun get(pos: Int): T {
TODO("implement")
}
fun addItem(item: T) {}
}
Bạn có thể tham chiếu T
như thể đó là một loại bình thường. Loại dữ liệu trả về cho get()
là T
và tham số tới addItem()
thuộc loại T
. Tất nhiên, danh sách chung rất hữu ích, vì vậy lớp List
được tích hợp vào Kotlin.
Bước 1: Tạo phân cấp loại
Ở bước này, bạn tạo một số lớp để sử dụng trong bước tiếp theo. Lớp học phụ đã được đề cập trong một lớp học lập trình trước đó, nhưng đây là một bài đánh giá ngắn.
- Để giữ cho ví dụ không bị lộn xộn, hãy tạo một gói mới trong src và gọi gói đó là
generics
. - Trong gói generic, hãy tạo một tệp
Aquarium.kt
mới. Điều này cho phép bạn xác định lại những thứ sử dụng cùng một tên mà không xung đột, vì vậy phần còn lại của mã cho phòng thí nghiệm mã này sẽ được đưa vào tệp này. - Tạo một hệ phân cấp loại nguồn cấp nước. Bắt đầu bằng cách đặt
WaterSupply
làm lớpopen
để có thể phân lớp con. - Thêm một tham số
var
boolean,needsProcessing
. Thao tác này sẽ tự động tạo một thuộc tính có thể thay đổi, cùng với một phương thức getter và setter. - Tạo một lớp con
TapWater
mở rộngWaterSupply
và chuyểntrue
choneedsProcessing
, vì nước nhấn có chứa các chất phụ gia không tốt cho cá. - Trong
TapWater
, hãy xác định một hàm có tên làaddChemicalCleaners()
để đặtneedsProcessing
thànhfalse
sau khi làm sạch nước. Bạn có thể đặt thuộc tínhneedsProcessing
từTapWater
vì nó làpublic
theo mặc định và các lớp con có thể truy cập được. Sau đây là mã hoàn chỉnh.
package generics
open class WaterSupply(var needsProcessing: Boolean)
class TapWater : WaterSupply(true) {
fun addChemicalCleaners() {
needsProcessing = false
}
}
- Tạo thêm hai lớp con của
WaterSupply
, được gọi làFishStoreWater
vàLakeWater
.FishStoreWater
không cần xử lý, nhưngLakeWater
phải được lọc bằng phương thứcfilter()
. Sau khi lọc, bạn không cần phải xử lý lại giá trị này, vì vậy, trongfilter()
, hãy đặtneedsProcessing = false
.
class FishStoreWater : WaterSupply(false)
class LakeWater : WaterSupply(true) {
fun filter() {
needsProcessing = false
}
}
Nếu bạn cần thêm thông tin, hãy xem lại bài học trước về tính kế thừa trong Kotlin.
Bước 2: Tạo lớp học chung
Trong bước này, bạn sửa đổi lớp Aquarium
để hỗ trợ nhiều loại vật tư nước.
- Trong tệp Aquarium.kt, hãy xác định một lớp
Aquarium
, trong đó dấu<T>
nằm ở sau tên lớp. - Thêm thuộc tính không thể thay đổi
waterSupply
thuộc loạiT
vàoAquarium
.
class Aquarium<T>(val waterSupply: T)
- Viết một hàm có tên là
genericsExample()
. Phần này không phải là một phần của lớp nên chúng có thể nằm ở cấp cao nhất của tệp, chẳng hạn như hàmmain()
hoặc định nghĩa lớp. Trong hàm này, hãy tạoAquarium
và chuyển hàm đó thànhWaterSupply
. Vì thông sốwaterSupply
là chung chung, bạn phải chỉ định loại trong dấu ngoặc nhọn<>
.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
}
- Trong
genericsExample()
, mã của bạn có thể truy cập vào thủy cungwaterSupply
. Vì thuộc loạiTapWater
nên bạn có thể gọiaddChemicalCleaners()
mà không cần bất kỳ loại truyền nào.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
aquarium.waterSupply.addChemicalCleaners()
}
- Khi tạo đối tượng
Aquarium
, bạn có thể xóa dấu ngoặc nhọn và nội dung giữa các giá trị này vì Kotlin có khả năng dự đoán loại. Vì vậy, không có lý do gì để nóiTapWater
hai lần khi bạn tạo phiên bản. Loại này có thể được suy ra bởi đối số choAquarium
; loại này vẫn sẽ tạoAquarium
thuộc loạiTapWater
.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
aquarium.waterSupply.addChemicalCleaners()
}
- Để xem điều gì đang xảy ra, hãy in
needsProcessing
trước và sau khi gọiaddChemicalCleaners()
. Dưới đây là hàm đã hoàn thành.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
println("water needs processing: ${aquarium.waterSupply.needsProcessing}")
aquarium.waterSupply.addChemicalCleaners()
println("water needs processing: ${aquarium.waterSupply.needsProcessing}")
}
- Thêm hàm
main()
để gọigenericsExample()
, sau đó chạy chương trình của bạn và quan sát kết quả.
fun main() {
genericsExample()
}
⇒ water needs processing: true water needs processing: false
Bước 3: Tạo thông tin cụ thể hơn
Chung chung có nghĩa là bạn có thể chuyển hầu hết mọi thứ, và đôi khi đó là một vấn đề. Trong bước này, bạn sẽ giúp lớp Aquarium
cụ thể hơn về những nội dung bạn có thể đưa vào.
- Trong
genericsExample()
, hãy tạo mộtAquarium
, chuyển một chuỗi chowaterSupply
, sau đó in thuộc tínhwaterSupply
của thủy cung.
fun genericsExample() {
val aquarium2 = Aquarium("string")
println(aquarium2.waterSupply)
}
- Chạy chương trình để quan sát kết quả.
⇒ string
Kết quả là chuỗi bạn đã vượt qua vì Aquarium
không đặt bất kỳ giới hạn nào trên T.
Mọi loại, kể cả String
, đều có thể được chuyển vào.
- Trong
genericsExample()
, hãy tạo mộtAquarium
khác, chuyểnnull
chowaterSupply
. NếuwaterSupply
là null, hãy in"waterSupply is null"
.
fun genericsExample() {
val aquarium3 = Aquarium(null)
if (aquarium3.waterSupply == null) {
println("waterSupply is null")
}
}
- Chạy chương trình và quan sát kết quả.
⇒ waterSupply is null
Tại sao bạn có thể chuyển null
khi tạo Aquarium
? Bạn có thể thực hiện việc này vì theo mặc định, T
là viết tắt của loại Any?
có thể có giá trị null, loại ở đầu hệ phân cấp loại. Nội dung sau đây tương đương với nội dung bạn đã nhập trước đó.
class Aquarium<T: Any?>(val waterSupply: T)
- Để không cho phép chuyển
null
, hãy đặtT
thuộc loạiAny
một cách rõ ràng bằng cách xóa?
sauAny
.
class Aquarium<T: Any>(val waterSupply: T)
Trong bối cảnh này, Any
được gọi là giới hạn chung. Điều này có nghĩa là bất kỳ loại nào cũng có thể được chuyển cho T
miễn là không phải null
.
- Điều bạn thực sự muốn đảm bảo là chỉ có thể chuyển
WaterSupply
(hoặc một trong các lớp con của lớp này) choT
. Hãy thay thếAny
bằngWaterSupply
để xác định một hạn chế chung chung hơn.
class Aquarium<T: WaterSupply>(val waterSupply: T)
Bước 4: Thêm chế độ kiểm tra khác
Trong bước này, bạn sẽ tìm hiểu về hàm check()
giúp đảm bảo mã của bạn hoạt động như dự kiến. Hàm check()
là một hàm thư viện chuẩn trong Kotlin. Hàm này đóng vai trò là một khẳng định và sẽ gửi một IllegalStateException
nếu đối số của đối số đánh giá thành false
.
- Thêm một phương thức
addWater()
vào lớpAquarium
để thêm nước, trong đó cócheck()
đảm bảo bạn không cần xử lý nước trước.
class Aquarium<T: WaterSupply>(val waterSupply: T) {
fun addWater() {
check(!waterSupply.needsProcessing) { "water supply needs processing first" }
println("adding water from $waterSupply")
}
}
Trong trường hợp này, nếu needsProcessing
đúng, check()
sẽ gửi một ngoại lệ.
- Trong
genericsExample()
, hãy thêm mã để tạoAquarium
vớiLakeWater
, sau đó thêm một ít nước vào thực thể đó.
fun genericsExample() {
val aquarium4 = Aquarium(LakeWater())
aquarium4.addWater()
}
- Chạy chương trình của bạn và bạn sẽ nhận được ngoại lệ vì nước cần được lọc trước.
⇒ Exception in thread "main" java.lang.IllegalStateException: water supply needs processing first at Aquarium.generics.Aquarium.addWater(Aquarium.kt:21)
- Hãy thêm một cuộc gọi để lọc nước trước khi thêm vào
Aquarium
. Hiện tại, khi bạn chạy chương trình, sẽ không có ngoại lệ nào được gửi.
fun genericsExample() {
val aquarium4 = Aquarium(LakeWater())
aquarium4.waterSupply.filter()
aquarium4.addWater()
}
⇒ adding water from generics.LakeWater@880ec60
Phần trên bao gồm những thông tin cơ bản về khái niệm chung. Những nhiệm vụ sau đây bao gồm nhiều chủ đề hơn, nhưng khái niệm quan trọng là cách khai báo và sử dụng một lớp chung chung có một hạn chế chung.
Trong tác vụ này, bạn sẽ tìm hiểu về loại trong và ngoài với loại chung. Loại in
là loại chỉ có thể chuyển được vào một lớp, không trả về được. Loại out
là một loại chỉ có thể được trả về từ một lớp.
Hãy xem lớp Aquarium
và bạn sẽ thấy rằng loại chung chỉ từng được trả về khi nhận thuộc tính waterSupply
. Không có phương thức nào lấy giá trị thuộc loại T
làm thông số (ngoại trừ để xác định giá trị này trong hàm dựng). Kotlin cho phép bạn xác định chính xác out
loại cho trường hợp này, đồng thời có thể dự đoán thêm thông tin về nơi an toàn để sử dụng các loại. Tương tự, bạn có thể xác định in
loại cho các loại chung chỉ từng được chuyển vào phương thức, không trả về. Điều này cho phép Kotlin thực hiện các bước kiểm tra bổ sung về độ an toàn của mã.
Loại in
và out
là các lệnh của hệ thống loại Kotlin. Việc giải thích toàn bộ hệ thống loại nằm ngoài phạm vi của chương trình đào tạo này (khó có liên quan); tuy nhiên, trình biên dịch sẽ gắn cờ các loại không được đánh dấu là in
và out
một cách phù hợp, vì vậy bạn cần phải biết về chúng.
Bước 1: Xác định loại không tham gia
- Trong lớp
Aquarium
, hãy đổiT: WaterSupply
thành loạiout
.
class Aquarium<out T: WaterSupply>(val waterSupply: T) {
...
}
- Trong cùng một tệp, nhưng ngoài lớp, hãy khai báo hàm
addItemTo()
dự kiếnAquarium
trongWaterSupply
.
fun addItemTo(aquarium: Aquarium<WaterSupply>) = println("item added")
- Gọi
addItemTo()
từgenericsExample()
và chạy chương trình.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
addItemTo(aquarium)
}
⇒ item added
Kotlin có thể đảm bảo rằng addItemTo()
sẽ không làm bất cứ loại nào không an toàn với WaterSupply
chung, vì loại này được khai báo là loại out
.
- Nếu bạn xóa từ khóa
out
, trình biên dịch sẽ báo lỗi khi gọiaddItemTo()
, vì Kotlin không thể đảm bảo rằng bạn không làm bất cứ điều gì không an toàn với loại đó.
Bước 2: Xác định loại
Loại in
tương tự như loại out
, nhưng đối với các loại chung chỉ từng được chuyển vào các hàm, sẽ không được trả về. Nếu cố gắng trả về loại in
, bạn sẽ gặp lỗi với trình biên dịch. Trong ví dụ này, bạn sẽ xác định một loại in
là một phần của giao diện.
- Trong Aquarium.kt, hãy xác định một giao diện
Cleaner
cóT
chung chung bị hạn chế ởWaterSupply
. Vì đối số này chỉ được dùng làm đối số choclean()
, nên bạn có thể đặt thông số này làm thông sốin
.
interface Cleaner<in T: WaterSupply> {
fun clean(waterSupply: T)
}
- Để sử dụng giao diện
Cleaner
, hãy tạo một lớpTapWaterCleaner
triển khaiCleaner
để dọn dẹpTapWater
bằng cách thêm hóa chất.
class TapWaterCleaner : Cleaner<TapWater> {
override fun clean(waterSupply: TapWater) = waterSupply.addChemicalCleaners()
}
- Trong lớp
Aquarium
, hãy cập nhậtaddWater()
để lấyCleaner
loạiT
và làm sạch nước trước khi thêm.
class Aquarium<out T: WaterSupply>(val waterSupply: T) {
fun addWater(cleaner: Cleaner<T>) {
if (waterSupply.needsProcessing) {
cleaner.clean(waterSupply)
}
println("water added")
}
}
- Hãy cập nhật mã mẫu
genericsExample()
để tạoTapWaterCleaner
,Aquarium
vớiTapWater
, sau đó thêm một ít nước bằng chất tẩy rửa. Ứng dụng sẽ dùng trình dọn dẹp này nếu cần.
fun genericsExample() {
val cleaner = TapWaterCleaner()
val aquarium = Aquarium(TapWater())
aquarium.addWater(cleaner)
}
Kotlin sẽ sử dụng thông tin về loại in
và out
để đảm bảo mã của bạn dùng chung chung. Out
và in
rất dễ nhớ: có thể chuyển out
loại ra bên dưới dưới dạng giá trị trả về, loại in
có thể được chuyển vào trong dưới dạng đối số.
Nếu bạn muốn tìm hiểu sâu hơn về các loại vấn đề trong loại và loại kết quả giải quyết, tài liệu sẽ trình bày chi tiết về các vấn đề đó.
Trong nhiệm vụ này, bạn sẽ tìm hiểu về các hàm chung và thời điểm sử dụng các hàm này. Thông thường, việc tạo một hàm chung là một ý tưởng tốt bất cứ khi nào hàm lấy đối số của một lớp có loại chung.
Bước 1: Tạo một hàm chung
- Trong tệp generic/Aquarium.kt, hãy tạo một hàm
isWaterClean()
nhận giá trịAquarium
. Bạn cần chỉ định loại chung của thông số; một tùy chọn là sử dụngWaterSupply
.
fun isWaterClean(aquarium: Aquarium<WaterSupply>) {
println("aquarium water is clean: ${aquarium.waterSupply.needsProcessing}")
}
Nhưng điều này có nghĩa là Aquarium
phải có thông số loại out
để được gọi. Đôi khi, out
hoặc in
quá hạn chế vì bạn cần sử dụng loại cho cả đầu vào và đầu ra. Bạn có thể xoá yêu cầu out
bằng cách đặt hàm này thành giá trị chung.
- Để tạo hàm chung, hãy đặt dấu ngoặc nhọn sau từ khoá
fun
với loại chungT
và mọi hạn chế, trong trường hợp này làWaterSupply
. Thay đổiAquarium
để bị hạn chế bởiT
thay vì trướcWaterSupply
.
fun <T: WaterSupply> isWaterClean(aquarium: Aquarium<T>) {
println("aquarium water is clean: ${!aquarium.waterSupply.needsProcessing}")
}
T
là một tham số loại của isWaterClean()
đang được dùng để chỉ định loại chung của thủy cung. Quy luật này rất phổ biến và bạn nên dành chút thời gian để tìm hiểu.
- Gọi hàm
isWaterClean()
bằng cách chỉ định loại trong dấu ngoặc nhọn ngay sau tên hàm và trước dấu ngoặc đơn.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
isWaterClean<TapWater>(aquarium)
}
- Do đối số
aquarium
dự đoán loại, nên loại không cần thiết, vì vậy, hãy xóa loại đối số này. Chạy chương trình và quan sát kết quả.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
isWaterClean(aquarium)
}
⇒ aquarium water is clean: false
Bước 2: Tạo một phương thức chung có loại đã được sửa đổi
Bạn cũng có thể dùng các hàm chung cho các phương thức, ngay cả trong những lớp có loại chung chung. Ở bước này, bạn thêm một phương thức chung vào Aquarium
để kiểm tra xem phương thức đó có loại WaterSupply
hay không.
- Trong lớp
Aquarium
, hãy khai báo một phương thức,hasWaterSupplyOfType()
nhận một thông số chungR
(T
đã được sử dụng) bị ràng buộc thànhWaterSupply
và trả vềtrue
nếuwaterSupply
thuộc loạiR
. Đây giống như hàm bạn đã khai báo trước đó, nhưng bên trong lớpAquarium
.
fun <R: WaterSupply> hasWaterSupplyOfType() = waterSupply is R
- Xin lưu ý rằng
R
cuối cùng được gạch dưới bằng màu đỏ. Giữ con trỏ lên để xem lỗi là gì. - Để kiểm tra
is
, bạn cần thông báo cho Kotlin rằng loại này đã được sửa chữa hoặc là thực và có thể dùng trong hàm. Để làm điều đó, hãy đặtinline
ở trước từ khóafun
vàreified
trước loại chung chungR
.
inline fun <reified R: WaterSupply> hasWaterSupplyOfType() = waterSupply is R
Sau khi loại bỏ một loại, bạn có thể sử dụng loại đó như một loại thông thường—vì đó là loại thực sau khi cùng dòng. Điều đó có nghĩa là bạn có thể kiểm tra is
bằng loại này.
Nếu bạn không dùng reified
ở đây, thì loại sẽ không được "real" đủ để Kotlin cho phép is
kiểm tra. Đó là vì các loại không được sửa đổi chỉ có sẵn tại thời điểm biên dịch và không thể sử dụng trong thời gian chạy bởi chương trình của bạn. Chúng tôi sẽ thảo luận thêm trong phần tiếp theo.
- Chuyển loại
TapWater
vào. Giống như gọi các hàm chung, hãy gọi các phương thức chung bằng cách sử dụng dấu ngoặc nhọn có loại đứng sau tên hàm. Chạy chương trình và quan sát kết quả.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.hasWaterSupplyOfType<TapWater>()) // true
}
⇒ true
Bước 3: Tạo hàm mở rộng
Bạn cũng có thể sử dụng các loại đã sửa đổi cho hàm thông thường và hàm mở rộng.
- Bên ngoài lớp
Aquarium
, hãy xác định một hàm mở rộng trênWaterSupply
có tên làisOfType()
. Hàm này kiểm tra xemWaterSupply
được chuyển có thuộc một loại cụ thể hay không, ví dụ nhưTapWater
.
inline fun <reified T: WaterSupply> WaterSupply.isOfType() = this is T
- Gọi hàm mở rộng giống như một phương thức.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.waterSupply.isOfType<TapWater>())
}
⇒ true
Với những hàm mở rộng này, bạn không cần phải chọn loại Aquarium
(Aquarium
hoặc TowerTank
hay lớp con khác), miễn là đó là Aquarium
. Sử dụng cú pháp star-projection là một cách thuận tiện để chỉ định nhiều kết quả trùng khớp. Và khi bạn sử dụng thao tác chiếu dấu sao, Kotlin sẽ đảm bảo bạn không làm bất kỳ điều gì không an toàn.
- Để sử dụng phép chiếu dấu sao, hãy đặt
<*>
sauAquarium
. Di chuyểnhasWaterSupplyOfType()
thành hàm mở rộng vì hàm này không thực sự là một phần của API cốt lõi củaAquarium
.
inline fun <reified R: WaterSupply> Aquarium<*>.hasWaterSupplyOfType() = waterSupply is R
- Thay đổi cuộc gọi thành
hasWaterSupplyOfType()
và chạy chương trình của bạn.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.hasWaterSupplyOfType<TapWater>())
}
⇒ true
Trong ví dụ trước, bạn phải đánh dấu loại chung là reified
và tạo hàm inline
vì Kotlin cần biết về các biến đó trong thời gian chạy, chứ không chỉ là thời gian biên dịch.
Tất cả các loại chung chỉ được sử dụng tại thời điểm biên dịch bằng Kotlin. Điều này cho phép trình biên dịch đảm bảo rằng bạn đang làm mọi thứ một cách an toàn. Theo thời gian chạy, tất cả các loại chung sẽ bị xóa, do đó thông báo lỗi trước đó về việc kiểm tra loại đã xóa.
Hóa ra trình biên dịch có thể tạo mã chính xác mà không cần giữ các loại chung cho đến thời gian chạy. Nhưng điều đó có nghĩa là đôi khi bạn làm điều gì đó, chẳng hạn như is
kiểm tra các loại chung chung, nên trình biên dịch không thể hỗ trợ. Đó là lý do Kotlin thêm loại được sửa đổi hoặc thực tế.
Bạn có thể đọc thêm trong bài viết Các loại dữ liệu sửa đổi và loại bỏ trong tài liệu về Kotlin.
Bài học này tập trung vào các thông tin chung, điều quan trọng để làm cho mã linh hoạt hơn và dễ sử dụng lại.
- Tạo các lớp chung để làm cho mã linh hoạt hơn.
- Thêm những hạn chế chung để giới hạn các loại được sử dụng chung.
- Dùng các loại
in
vàout
với loại chung để kiểm tra loại tốt hơn nhằm hạn chế các loại được chuyển vào hoặc trả về từ lớp. - Tạo các hàm và phương thức chung để làm việc với các loại chung. Ví dụ:
fun <T: WaterSupply> isWaterClean(aquarium: Aquarium<T>) { ... }
- Dùng các hàm mở rộng chung để thêm chức năng không phải cốt lõi vào một lớp.
- Đôi khi, bạn cần tạo lại các loại bổ sung vì việc xóa loại. Không giống như các loại chung, các loại đã sửa sẽ tiếp tục có thời gian chạy.
- Hãy sử dụng hàm
check()
để xác minh mã của bạn đang chạy như mong đợi. Ví dụ:check(!waterSupply.needsProcessing) { "water supply needs processing first" }
Tài liệu về Kotlin
Nếu bạn muốn biết thêm thông tin về bất kỳ chủ đề nào trong khóa học này hoặc nếu bạn gặp khó khăn, https://kotlinlang.org là điểm khởi đầu tốt nhất của bạn.
- Chung
- Các hạn chế chung
- Dự kiến có gắn dấu sao
- Loại
In
vàout
- Thông số đã sửa đổi
- Xóa loại
- Hàm
check()
Hướng dẫn về Kotlin
Trang web https://try.kotlinlang.org có các hướng dẫn phong phú được gọi là Kotlin Koans, một biên dịch viên dựa trên web và một bộ tài liệu tham khảo đầy đủ có các ví dụ.
Khóa học Udacity
Để xem khóa học Udacity về chủ đề này, hãy xem Kotlin Bootcamp dành cho lập trình viên.
IntelliJ IDEA
Bạn có thể tìm thấy tài liệu về IntelliJ IDEA trên trang web của JetBrains.
Phần này liệt kê các bài tập về nhà có thể được giao cho học viên đang làm việc qua lớp học lập trình này trong khóa học do người hướng dẫn tổ chức. Người hướng dẫn có thể làm những việc sau:
- Giao bài tập về nhà nếu được yêu cầu.
- Trao đổi với học viên cách nộp bài tập về nhà.
- Chấm điểm bài tập về nhà.
Người hướng dẫn có thể sử dụng những đề xuất này ít hay nhiều tùy ý. Do đó, họ có thể thoải mái giao bất kỳ bài tập về nhà nào khác mà họ cảm thấy phù hợp.
Nếu bạn đang tự mình làm việc qua lớp học lập trình này, hãy thoải mái sử dụng các bài tập về nhà này để kiểm tra kiến thức của bạn.
Trả lời các câu hỏi sau
Câu hỏi 1
Quy ước nào sau đây quy ước để đặt tên cho loại chung?
▢ <Gen>
▢ <Generic>
▢ <T>
▢ <X>
Câu hỏi 2
Hạn chế đối với các loại được cho phép đối với loại chung được gọi:
▢ hạn chế chung
▢ một hạn chế chung
▢ định nghĩa
▢ giới hạn loại chung
Câu hỏi 3
Có nghĩa là:
▢ Hệ thống đã tính toán tác động thực thi của một đối tượng.
▢ Một chỉ mục nhập bị hạn chế đã được đặt trên lớp này.
▢ Hệ thống đã tạo thông số loại chung thành loại thực.
▢ Một chỉ báo lỗi từ xa đã được kích hoạt.
Chuyển sang bài học tiếp theo:
Để biết thông tin tổng quan về khóa học, bao gồm cả các đường liên kết đến các lớp học lập trình khác, hãy xem "Kotlin Bootcamp dành cho lập trình viên: Chào mừng bạn đến với khóa học này?