文章內(nèi)容主要是基于傳智播客《kotlin從零基礎(chǔ)到進(jìn)階》的視頻做的筆記。
標(biāo)題中的 V 是Video的縮寫,V4 就是對應(yīng)視頻中的第四個視頻。
V4、程序入口--main函數(shù)

V5、變量與輸出
1、變量的聲明:
var name=“張三” //變量聲明關(guān)鍵詞 var , 語句末尾不需要分號
2、數(shù)據(jù)額類型

V6、二進(jìn)制基礎(chǔ)


V7、類型推斷和顯示類型聲明(變量和常量的聲明)
1、類型推斷
- 在聲明一個變量時,我們可以不需要顯示聲明數(shù)據(jù)類型,kotlin 會根據(jù)你為變量賦的值動態(tài)的推導(dǎo)出其類型。
- 當(dāng)一個變量被賦予了某個類型的數(shù)值之后,不能再賦給他其他類型的數(shù)值,否則,會報 類型錯誤。
fun main(args:Array<String>){
var a=10 //聲明變量a , 將int類型的10 賦值給a, a 將只能接受int型數(shù)據(jù)
a=15
//a="字符串" //將字符串類型的數(shù)據(jù)賦值給int型的a ,報錯??!
var s="字符串"
}
2、顯示類型聲明
格式:var 變量名:變量類型=值
var a:Int=10
3、變量聲明的注意事項
- 如果聲明變量時就賦初值,可以不寫類型,此時,類型推導(dǎo)將生效
- 如果聲明變量時沒有賦初值,則必須寫明類型,否則會報錯。格式:
var a:Int
4、常量的聲明
關(guān)鍵字:val
格式:val 常量名:常量類型=常量值
V8、變量的取值范圍
獲取某種類型數(shù)據(jù)的最大最小值
fun main(args:Array<String>){
val minByte:Byte=Byte.MIN_VALUE
val maxByte:Byte=Byte.MAX_VALUE
val a:Int=0b0011 //將二進(jìn)制的0b0011 轉(zhuǎn)換為10進(jìn)制,并復(fù)制給a
}
- Byte、Int、Long 可以通過上述方式獲取最大最小值
- String 沒有最大最小值,所以沒有上述方法
V9、Kotlin函數(shù)入門
- main() 程序入口
- println() 打印
函數(shù)聲明基本格式:fun 函數(shù)名(參數(shù):參數(shù)類型){函數(shù)體}
V10、Boolean運(yùn)算
Math.sqrt(5.0) //sqrt()--開根號,獲取5.0的開根值,即根號5的值
Math.pow(2.0,100.0) //pow()--冪函數(shù),計算2的100次方
V11、命令行交互式工具
不實用,內(nèi)容省略。
V12、函數(shù)加強(qiáng)
函數(shù)命名格式說明:
fun 函數(shù)名(參數(shù):參數(shù)類型):返回值類型{
函數(shù)體
}
- 如果沒有返回值,使用 :Unit 標(biāo)識,也可以省略不寫
- 返回值也是使用 return 返回。
V13、函數(shù)聲明練習(xí)題
內(nèi)容省略
V14、字符串模板
“ ” ,被兩個雙引號包裹的內(nèi)容是普通字符串,支持轉(zhuǎn)義字符
“”“ ”“” ,被一對三引號包裹的內(nèi)容是原樣字符串,不支持轉(zhuǎn)義字符,其中的內(nèi)容被定義成什么樣,輸出的時候就是什么樣。
字符串模板格式:${占位字符串}
V15、條件控制--if、else
基本格式:
if(條件){
//DO STH
}else{
//DO STH
}
詳細(xì)可參考:http://www.itdecent.cn/p/b8eb0fe28dad
V16、字符串比較
var str1="張三" // = 是賦值
var str2="李四"
boolean flag=str1==str2 // == 是比較,等同于 Java中的 equals()
可以使用 == 比較字符串
-
也可以使用 equals(,) 方法比較字符串,該方法第二個參數(shù)表示是否忽略大小寫,true--忽略大小寫,false--不忽略大小寫。
- equals(,) 中第二個參數(shù)為 true時 效果等價于Java中的 equalsIgnoreCase()
V17、空值處理
- 以 null 表示空值
- kotlin 中定義方法時,默認(rèn)接收的是 非 null 參數(shù)。
- 如果定義某個方法可以接收 null參數(shù),則在聲明方法參數(shù)時在參數(shù)后面加上?。示例如下:
fun test(str1:String?){ //String 后面的 ? 就表示該方法可以接收 null 作為參數(shù)
//DO STH
}
V18、When表達(dá)式
類似于Java中的switch
基本使用格式:
when(變量){
分支A -> 表達(dá)式
else -> 表達(dá)式
}
帶有返回值的When表達(dá)式:
var result=when(變量){
分支A -> 表達(dá)式(要有返回值,最終將值賦給result)
else -> 表達(dá)式(要有返回值,最終將值賦給result)
}
詳細(xì)參考:http://www.itdecent.cn/p/b8eb0fe28dad
V19、Loop和Range
- 聲明一個區(qū)間數(shù)組
var nums1=1..100 //表示我們聲明了一個閉區(qū)間數(shù)組,其中包含的數(shù)值為 1-100。 .. 表示閉區(qū)間
var nums2=1 util 100 //前閉后開區(qū)間,取值 1-99. util 表示前閉后開區(qū)間
- for 基本循環(huán)格式
for(變量 in 數(shù)組或字符串){
//DO STH
}
- 帶有步進(jìn)的for循環(huán)
for (變量 in 數(shù)組 step 步進(jìn)數(shù)量){ //所謂步進(jìn),就是遞增幅度。默認(rèn)步進(jìn)為1
//DO STH
}
- 數(shù)組.reversed() //數(shù)組內(nèi)容反轉(zhuǎn)
- 數(shù)組.count() //獲取數(shù)組的容量,等價于Java中的 數(shù)組.length
詳細(xì)參考:http://www.itdecent.cn/p/b8eb0fe28dad
V20、List 和 Map
1、List
- List的基本聲明格式:
var list1=listOf(元素1,元素2,元素3) //聲明List時主要是通過 listOf()實現(xiàn)
- 使用 for 循環(huán)同時遍歷索引和索引對應(yīng)的數(shù)值
for((index,value) in list.withIndex()){ //重點是 withIndex() 方法,index 接收索引,value 接收對應(yīng)的值
//DO STH
}
2、Map (詞典)
- 基本聲明格式:
var map=TreeMap<鍵類型,值類型>()
map[key]=value
- 示例代碼:
var map=TreeMap<String,String>() //聲明 map
map["好"]=good
map["學(xué)習(xí)"]=study //添加鍵值對元素
println(map["好"]) //取值并打印
V21、函數(shù)和函數(shù)表達(dá)式
1、函數(shù)的簡化
//原函數(shù):
fun sum(a:Int , b:Int):Int{
return a+b
}
//簡化后
fun sum(a:Int , b:Int):Int=a+b
2、使用 var 聲明函數(shù)——函數(shù)表達(dá)式1(重點!)
kotlin 中除了使用基本的 fun 關(guān)鍵字聲明函數(shù)外,還可以使用 var 聲明。示例如下:
var i={x:Int , y:Int -> x+y} //聲明函數(shù)i,接收兩個Int類型參數(shù) x、y,返回 x+y 的值
i(3,5) //調(diào)用使用 var 聲明的函數(shù) i
3、使用 var 聲明函數(shù)——函數(shù)表達(dá)式2(重點!)
var j:(Int,Int)->Int={x,y -> x+y} //聲明函數(shù)j,它接收的參數(shù)是兩個Int, 返回一個Int,對應(yīng)的表達(dá)式是 {x,y->x+y}
j(4,4) //調(diào)用函數(shù)
詳細(xì)參考:http://www.itdecent.cn/p/da4a93a356d6
V22、默認(rèn)參數(shù)和具名參數(shù)
- 具有默認(rèn)參數(shù)值得函數(shù)聲明
val Pi=3.1415926
fun getRoundArea(PI:Float=Pi , radius:Float):Float{ //為變量PI賦予了默認(rèn)值 Pi,這樣,調(diào)用該方法時可以不再傳遞PI。但,如果我們想傳入的值和默認(rèn)值不一致時還是需要傳入的
return PI*radius*radius
}
- 調(diào)用帶有默認(rèn)參數(shù)值的函數(shù)
var a=getRoundArea(3.14f,5.0f) //因為我們相傳入的PI和默認(rèn)值不一致,所以,需要將3.14f傳入
- 具名參數(shù)的使用
所謂具名參數(shù),就是調(diào)用某個方法時指明傳入的參數(shù)是給哪個變量的。
var a=getRoundArea(radius=5.0f) //我們需要的PI值與默認(rèn)值一致,此時不需要再傳入PI值。只需要通過 radius=5.0f 聲明我們傳入了半徑值
v23、字符串和數(shù)字的轉(zhuǎn)換
var a="13"
a.toInt() //字符串轉(zhuǎn)換為Int
var b=13
b.toString() //Int轉(zhuǎn)換為字符串
V24、人機(jī)交互--根據(jù)用戶輸入的數(shù)字動態(tài)計算Sum
意念交互、語音交互、眼動跟蹤、體感交互、打字交互
fun main(array:ArrayList<String>){
println(“請輸入第一個數(shù)值”)
var a=readLine() //讀取鍵盤輸入的字符串內(nèi)容,并賦值給a
println(“請輸入第二個數(shù)值”)
var b=readLine()
var num1=a!!.toInt() //readLine()得到的可能是null,所以此處通過 !! 斷言輸入不為null
var num2=b!!.toInt()
println("${num1}+${num2}=${num1+num2}")
}
V25、異常處理
異常處理格式:--同Java
try{
//可能會出錯的代碼塊
}catch(e:Excepiton){
//出錯之后的處理邏輯
}
V26、遞歸
1、利用遞歸實現(xiàn) 階乘函數(shù)
fun fact(a:Int):Int{
if(a==1){
return 1
}else{
return a*fact(a-1) //函數(shù)內(nèi)調(diào)用函數(shù)本身就成為了遞歸
}
}
2、BigInteger
在上面的方法中,我們用 Int 來接收階乘的值,但是如果我們輸入 100 ,會發(fā)現(xiàn)最終返回的值是 0, 是因為 100的階乘超過了 Int的范圍。所以,此時我們就需要使用到 BigInteger。
BigInteger 用來表示一個超大值。
import java.math.BigInteger
fun main(array: Array<String>) {
val num = BigInteger("50") //聲明BigInteger常量時傳入一個字符串類型的數(shù)值
println(fact(num))
}
fun fact(num: BigInteger): BigInteger {
return if (num == BigInteger.ONE) {
BigInteger.ONE
} else {
num * fact(num - BigInteger.ONE)
}
}
V27、尾遞歸優(yōu)化
1、什么是尾遞歸?(點擊查看阮一峰老師關(guān)于尾遞歸的介紹)
- 尾遞歸 :是指某個函數(shù)的最后一步依舊是調(diào)用自身
- kotlin中尾遞歸關(guān)鍵字 tailrec
2、為什么需要尾遞歸優(yōu)化?
遞歸非常耗費(fèi)內(nèi)存,因為需要同時保存成千上百個調(diào)用記錄,很容易發(fā)生"棧溢出"錯誤(stack overflow)。但 對于尾遞歸來說,由于只存在一個調(diào)用記錄,所以永遠(yuǎn)不會發(fā)生"棧溢出"錯誤。
3、使用尾遞歸實現(xiàn)累加
fun main(args: Array<String>) {
println(accumulation(5, 1))
}
/**
* tailrec 是尾遞歸函數(shù)的關(guān)鍵字
* 尾遞歸函數(shù)是指,在該函數(shù)的最后一步操作中依舊是調(diào)用函數(shù)本身
* 為了實現(xiàn)尾遞歸,我們定義了該方法接收兩個參數(shù):num 是我們傳入的需要計算累加值得的變量,total用來接收最終的返回值
*/
tailrec fun accumulation(num: Int, total: Int): Int {
return if (num == 1) {
total
} else {
accumulation(num - 1, num + total) //此時,該調(diào)用的含義是:先計算 total=num+total,然后計算 num=num-1
}
}
V28、IDEA介紹
內(nèi)容省略。
IDEA開發(fā)環(huán)境的搭建可以參考:http://www.itdecent.cn/p/5a3e56f90b7f
V29、面向?qū)ο笕腴T——定義一個類并構(gòu)建對象
//定義一個類,包含兩個成員變量 height和width
class Rect(var height:Int,var width:Int)
fun main(args: Array<String>) {
var rect=Rect(5,10) //構(gòu)建Rect對象,不需要new
println("矩形的寬${rect.width}高${rect.height}") //引用Rect類中成員變量
}
V30、靜態(tài)屬性和動態(tài)行為/方法——為類定義成員方法
//定義一個類,包含兩個成員變量 height和width.并定義一個成員方法
class Rect(var height: Int, var width: Int) {
fun getArea(a: Int, b: Int): Int = a * b
}
fun main(args: Array<String>) {
var rect = Rect(5, 10) //構(gòu)建Rect對象,不需要new
println("矩形的寬${rect.width}高${rect.height}") //引用Rect類中成員變量
println("矩形的面積是${rect.getArea(rect.width, rect.height)}") //引用Rect類中成員變量
}
V31、面向?qū)ο蟮母拍罱忉?/h2>
沒有實際內(nèi)容,所以省略
V32、面向?qū)ο?-洗衣機(jī)洗衣服案例
1、新建 WashMachine 類文件
//定義成員變量和成員方法
class WashMachine(var brand: String, var size: Int) { //品牌,容量
fun openTheDoor() {
println("打開洗衣機(jī)的門")
}
fun closeTheDoor() {
println("關(guān)上洗衣機(jī)的門")
}
fun start() {
println("啟動洗衣機(jī)洗衣服")
}
}
2、引用WashMachine類執(zhí)行洗衣服的操作
fun main(args: Array<String>) {
var washMachine = WashMachine("小天鵝", 15) //構(gòu)建對象
washMachine.openTheDoor()
washMachine.closeTheDoor()
washMachine.start()
}
V33、面向?qū)ο蟆壈嫦匆聶C(jī)案例
1、升級版洗衣機(jī)邏輯--檢測門的開啟狀態(tài)和轉(zhuǎn)速模式
class WashMachine(var brand: String, var size: Int) {
var isDoorOpen = false
var curMode = 0
fun openTheDoor() {
println("打開洗衣機(jī)的門")
isDoorOpen = true
}
fun closeTheDoor() {
println("關(guān)上洗衣機(jī)的門")
isDoorOpen = false
}
fun selectMode(mode: Int) {
curMode = mode
when (mode) {
0 -> println("慢速模式")
1 -> println("標(biāo)準(zhǔn)模式")
2 -> println("快速模式")
else -> println("初始狀態(tài)")
}
}
fun start() {
if (isDoorOpen) {
println("洗衣機(jī)的門還沒有關(guān)閉")
} else {
when (curMode) {
0 -> {
println("您選擇的是慢速模式,發(fā)動機(jī)轉(zhuǎn)速慢")
println("啟動洗衣機(jī)洗衣服")
}
1 -> {
println("您選擇的是標(biāo)準(zhǔn)模式,發(fā)動機(jī)常速運(yùn)轉(zhuǎn)")
println("啟動洗衣機(jī)洗衣服")
}
2 -> {
println("您選擇的是快速模式,發(fā)動機(jī)轉(zhuǎn)速快")
println("啟動洗衣機(jī)洗衣服")
}
else -> println("您還沒有選擇轉(zhuǎn)速模式,發(fā)動機(jī)不會運(yùn)轉(zhuǎn),不執(zhí)行洗衣操作")
}
}
}
}
2、引用洗衣機(jī)對象洗衣服
fun main(args: Array<String>) {
var washMachine = WashMachine("小天鵝", 15)
washMachine.openTheDoor()
washMachine.closeTheDoor()
washMachine.selectMode(1) //加入了模式選擇
washMachine.start()
}
V34、面向?qū)ο蟆庋b
- 隱藏內(nèi)部實現(xiàn)細(xì)節(jié)即為封裝——Java系的程序員都知道!
- 私有關(guān)鍵字 :private —— 同Java。私有即是封裝的一種體現(xiàn)
V35、面向?qū)ο蟆^承
- 一個對象直接使用另一個對象的屬性或方法 —— 同Java
- 被繼承的父類必須用 open 修飾,表示允許其他類繼承該類
- 父類中的方法如果允許子類重寫,也需要用 open 修飾
- 重寫父類方法時需要用 overRide 修復(fù)重寫后的方法
- 繼承的格式:
class 子類:父類()
父類
open class Father { //用 open 修飾,允許被繼承
var character = "性格內(nèi)向"
open fun action() { //用open修飾,允許被重寫
println("喜歡讀書")
}
}
子類:
class Son : Father() { //繼承。 Son 繼承自 Father
override fun action() { //重寫父類方法
//super.action()
println("兒子的性格是$character")
println("兒子不喜歡看書,但是喜歡唱歌")
}
}
V36、抽象類及其實現(xiàn)
- 抽象的關(guān)鍵字 abstract —— 同Java
- 抽象類和方法不需要用 open 聲明可以被繼承/實現(xiàn)
抽象類Human
abstract class Human (var name: String){ //定義抽象類,使用 abstract 修飾。包含成員變量name
abstract fun eat() //定義抽象方法, 使用 abstract 修飾
}
抽象類的子類Man
class Man(name: String) : Human(name) { //繼承自Human抽象類
override fun eat() { //必須重寫抽象方法
println("${name}是男人,是家中勞力,所以吃的多")
}
}
調(diào)用子類
fun main(args: Array<String>) {
var man=Man("張三")
man.eat()
}
V37、多態(tài)
- 同種功能,不同的表現(xiàn)形式 即為 多態(tài)
視頻中用男人和女人的尿尿姿勢來解釋多態(tài),很形象哈
抽象類Human
abstract class Human(var name: String) { //定義抽象類,使用 abstract 修飾。包含成員變量name
abstract fun eat() //定義抽象方法, 使用 abstract 修飾
abstract fun pee() //定義抽象方法
}
子類Man
class Man(name: String) : Human(name) {
override fun pee() {
println("${name}是男人,是站著尿尿的")
}
override fun eat() {
println("${name}是男人,是家中勞力,所以吃的多")
}
}
子類Woman
class Woman(name: String) : Human(name) {
override fun eat() {
println("${name}是女人,飯量比較小")
}
override fun pee() {
println("${name}是女人,是蹲著尿尿的")
}
}
外部調(diào)用
fun main(args: Array<String>) {
var man=Man("張三")
var woman=Woman("小花")
var list= listOf<Human>(man,woman) //定義集合
for (human in list){ //遍歷集合
human.pee()
}
}
V38、接口及其實現(xiàn)
- 接口--數(shù)據(jù)有進(jìn)有出的交互方式、
- 接口關(guān)鍵字:interface —— 同Java
- 接口是事物的能力(代表某種事物的特性),抽象類是事物的本質(zhì)(代表的是一類事物的共性)
- 子類實現(xiàn)接口時,接口名后面不需要()
定義接口IMan
interface IMan { //定義一個男人的接口
fun xiaodidi()
}
Man類實現(xiàn)IMan接口
class Man(name: String) : Human(name) ,IMan{ //男人屬于人,所以繼承Human;男人有小弟弟,所以實現(xiàn) IMan接口
override fun xiaodidi() {
println("這是重寫IMan接口中的方法——男人有小弟弟")
}
override fun pee() {
println("${name}是男人,是站著尿尿的")
}
override fun eat() {
println("${name}是男人,是家中勞力,所以吃的多")
}
}
太監(jiān)不能實現(xiàn)IMan接口
class TaiJian(name: String) : Human(name) { //太監(jiān)屬于人,但是太監(jiān)沒有小弟弟,所以不能實現(xiàn) IMan接口
override fun eat() {
println("太監(jiān)也能吃飯")
}
override fun pee() {
println("太監(jiān)也會尿尿")
}
}
V39、代理和委托——大頭兒子和小頭爸爸的洗碗案例
- 委托,把自己不干的事情交給別人做
- 代理,做別人委托的事情
- kotlin中接口代理關(guān)鍵字:by
1、場景說明
圍裙媽媽只負(fù)責(zé)做飯,不負(fù)責(zé)洗碗
小頭爸爸洗一次碗可以賺到10元
大頭兒子洗一次碗可以賺到1元
小頭爸爸承攬了洗碗的活,最終交給大頭兒子做,中間賺了9元差價
2、代碼實現(xiàn)——完全委托
(1)、定義洗碗的接口
interface IWashBow { //定義一個洗碗接口,包含一個洗碗方法
fun washBow()
}
(2)、大頭兒子實現(xiàn)接口
class BigHeadSon:IWashBow { //被實現(xiàn)的接口后面不需要加()
override fun washBow() {
println("我是大頭兒子,每次洗碗賺1元錢")
}
}
(3)、小頭爸爸實現(xiàn)接口并委托事件給小頭兒子
class SmallHeadFather:IWashBow by BigHeadSon(){ //委托關(guān)鍵字 by;被委托方(即代理方)如果不是單例類,則后面需要跟()
}
(4)、程序調(diào)用及輸出結(jié)果
fun main(args: Array<String>) {
var father=SmallHeadFather()
father.washBow() //小頭爸爸已經(jīng)將洗碗的操作委托為小頭兒子了,所以,此處本質(zhì)是調(diào)用的小頭兒子的洗碗操作
}

V40、單例模式
-
單例關(guān)鍵字:object
我們在定義一個類時,使用object 替換 class 來修飾這個類,就表示,這是一個單例類 - 單例類作為代理人時,不需要()
1、場景說明
小頭爸爸為了增進(jìn)父子感情,想和小頭兒子一起洗碗
3、代碼實現(xiàn)
(1)、小頭爸爸重寫接口方法 —— 未使用單例時的錯誤寫法
class SmallHeadFather:IWashBow by BigHeadSon(){
override fun washBow() {
println("我是小頭爸爸,我把洗碗事件委托給了大頭兒子")
BigHeadSon().washBow() //委托方重寫了事件之后,需要手動調(diào)用代理方的方法。但是,此處又通過()構(gòu)建了一個小頭兒子對象,已經(jīng)不再是我們初始委托的那個大頭兒子了。所以,此處是有問題的。
println("我是小頭爸爸,大頭兒子洗完碗之后,我賺了9元")
}
}
(2)、使用單例后的正確寫法:
大頭兒子單例類
object BigHeadSon:IWashBow { //單例關(guān)鍵字object,聲明為單例類之后會立即在內(nèi)存中創(chuàng)建單例對象,并一直存在
override fun washBow() {
println("我是大頭兒子,每次洗碗賺1元錢")
}
}
小頭爸爸委托事件給單例的大頭兒子
class SmallHeadFather:IWashBow by BigHeadSon{ //被委托方(即代理方)是單例類,不需要通過()構(gòu)建對象
override fun washBow() {
println("我是小頭爸爸,雖然我把洗碗事件委托給了小頭兒子,但是我要和他一起洗碗")
BigHeadSon.washBow() //委托方重寫了事件之后,需要手動調(diào)用代理方的方法。由于 BigHeadSon是單例的,所以,這還是我們之前委托的那個兒子
println("我是小頭爸爸,我和小頭兒子洗完碗之后,我賺了9元")
}
}
(3)、外部調(diào)用
fun main(args: Array<String>) {
var father=SmallHeadFather()
father.washBow() //小頭爸爸已經(jīng)將洗碗的操作委托為小頭兒子了,但因為重寫了洗完事件,所以,本子是調(diào)用的父親的洗完事件,父親的洗完事件中有一部分是自己做的,另一部分是兒子做的
}
(4)、輸出結(jié)果

V41、枚舉--enum
枚舉示例代碼
enum class Week { //枚舉關(guān)鍵字 enum
星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期天
}
fun main(args: Array<String>) {
println(Week.星期一)
println("${Week.星期一}在Week中的索引是${Week.星期一.ordinal}")
}
運(yùn)行結(jié)果

V42、印章類/密封類 (Sealed Class)
1、印章類的特點
- 子類類型有限的類成為 印章類/密封類
- 印章類使用 sealed 作為修飾符
- 印章類本身沒有構(gòu)造方法
2、印章類與枚舉的區(qū)別
- 都是有限的數(shù)據(jù)
- 枚舉更注重具體的數(shù)據(jù)
- 印章類更注重數(shù)據(jù)的類型
3、印章類示例代碼
(1)、場景說明
假設(shè)你家有一頭公驢、一頭母驢、一頭公馬。那么,
它們可能會生出一頭小驢,
也可能會生出一頭小騾子。
(2)、代碼示例
在上述場景中,由于他們能生出的兒子類型時固定的,所以,我們可以使用印章類來標(biāo)識。
聲明印章類
sealed class Son { //使用 sealed 聲明 Son 為印章類/密封類
class SmallMule() : Son() //聲明小騾子 SmallMule 為 Son的子類。
class SmallDonkey() : Son() //聲明小驢子 SmallDonkey 為 Son的子類
fun sayHello(son: Son) {
if (son is SmallMule) { //判斷是不是XX的實例的關(guān)鍵字 is
println("小騾子對大家說大家好")
} else if (son is SmallDonkey) {
println("小驢子對大家說大家好")
}
}
}
調(diào)用印章類
fun main(args: Array<String>) {
var mule = Son.SmallMule()
var donkey = Son.SmallDonkey()
var list = listOf<Son>(mule, donkey)
for (son in list) {
son.sayHello(son)
}
}
運(yùn)行結(jié)果

Kotlin基礎(chǔ)到此完結(jié),之后需要研究的內(nèi)容
- 游戲開發(fā)和游戲引擎(lwjgj)
- Lambda 表達(dá)式
- 高階函數(shù)
- DSL (特定領(lǐng)域語言)
- 使用Kotlin進(jìn)行Android開發(fā)
- 使用Kotlin開發(fā)SpringBoot引用
附上Kotlin資料含視頻和電子書:
點擊進(jìn)入百度網(wǎng)盤下載
資料截圖如下:

聲明:以上資料均來源于網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系我刪除
本文到此結(jié)束,謝謝觀看!
如有不足,敬請指正!
CnPeng 微信公眾號上線了!!
我們不僅可以聊軟件,還可以聊硬件;
我們不僅可以聊技術(shù),還可以聊人生。
這,是一個不羈的公眾號。
歡迎掃描下方二維碼調(diào)戲!
