Kotlin面向?qū)ο笾R(shí)點(diǎn)講解
類和對(duì)象
創(chuàng)建一個(gè)Person類
open class Person { /** * 姓名 */ var name = "" /** * 年齡 */ var age = 0 /** * 人的吃飯方法 */ fun eat() { print(name + " is eating. He is" + age +"years old.") } }
在main函數(shù)中創(chuàng)建Person對(duì)象,對(duì)字符進(jìn)行賦值,調(diào)用類中的方法
fun main() { val p = Person(); p.name = "張三" p.age = 10 p.eat() }
注意在Kotlin當(dāng)中創(chuàng)建對(duì)象不需要new關(guān)鍵字
繼承和構(gòu)造函數(shù)
- 繼承是面向?qū)ο蟮囊淮筇匦?/li>
- 在Kotlin中和java不同的是,在Koitlin中任何一個(gè)非抽象類都是默認(rèn)不可以被繼承的,就相當(dāng)于在java中給一個(gè)類加上了final關(guān)鍵字
- 因?yàn)樵谝槐久麨镋ffective Java中的書明確提到,如果一個(gè)類不是專門為了繼承而設(shè)計(jì)的,那么他就應(yīng)該加上final聲明,禁止它可以被繼承,這個(gè)屬于就是編程規(guī)范了
- 在Kotlin當(dāng)中的抽象類和java并沒有什么區(qū)別
- 在Kotlin中如果想要一個(gè)類可以被繼承,只需要在這個(gè)類的前面加上open關(guān)鍵字即可
- 如果一個(gè)類要繼承一個(gè)類的話,在java當(dāng)中使用的是extends關(guān)鍵字,在Kotlin當(dāng)中使用的是 : 這個(gè)關(guān)鍵字,而且父類不僅僅要寫出類名還要帶上一對(duì)括號(hào)
class Student : Person() { var sno = "" var grade = 0 }
Kotlin中類的主構(gòu)造函數(shù)
每個(gè)類都會(huì)默認(rèn)有一個(gè)不帶參數(shù)的主構(gòu)造函數(shù),但是我們也可以顯示的給他指定參數(shù),主構(gòu)造函數(shù)的特點(diǎn)是沒有函數(shù)體,直接定義在類名的后面即可
class Student(val sno: String, val grade: Int) { }
上面這行代碼就表示Student的主構(gòu)造函數(shù)有兩個(gè)參數(shù),分別是sno和grade
在主構(gòu)造函數(shù)當(dāng)中沒有函數(shù)體,那么我們想要在主構(gòu)造函數(shù)當(dāng)中編寫一些代碼邏輯也是可以的,我們可以通過init結(jié)構(gòu)體來進(jìn)行實(shí)現(xiàn)
class Student(val sno: String, val grade: Int) { init { println("sno is " + sno) println("grade is" + grade) } }
通過init結(jié)構(gòu)體就可以擴(kuò)展的為主構(gòu)造函數(shù)執(zhí)行一些代碼邏輯
那么子類在繼承父類的時(shí)候,為什么父類名后面要跟上一對(duì)括號(hào)呢,原因是,子類在繼承父類的時(shí)候,子類的構(gòu)造函數(shù)必須調(diào)用父類的構(gòu)造函數(shù),所以子類的主構(gòu)造函數(shù)調(diào)用父類的那個(gè)構(gòu)造函數(shù),就是由這個(gè)()來進(jìn)行指定的.
class Student : Person() { var sno = "" var grade = 0 }
在這里Person類后面一對(duì)空括號(hào)表示Student類的主構(gòu)造函數(shù)在初始化的時(shí)候會(huì)調(diào)用Person類的無參構(gòu)造函數(shù)
次構(gòu)造函數(shù):在Kotlin當(dāng)中,每一個(gè)類只能有一個(gè)主構(gòu)造函數(shù),但是可以有多個(gè)次構(gòu)造函數(shù),次構(gòu)造函數(shù)也可以實(shí)例化一個(gè)類,區(qū)別就是主構(gòu)造函數(shù)沒有函數(shù)體,次構(gòu)造函數(shù)有函數(shù)體
Kotlin規(guī)定,在一個(gè)類當(dāng)中如果同時(shí)存在主構(gòu)造函數(shù)和次構(gòu)造函數(shù)的時(shí)候,所有的次構(gòu)造函數(shù)必須調(diào)用主構(gòu)造函數(shù)(包含間接調(diào)用)
次構(gòu)造函數(shù)通過construtor關(guān)鍵字來進(jìn)行聲明
class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age) { //次構(gòu)造函數(shù)1:直接調(diào)用本類的主構(gòu)造函數(shù),這個(gè)次構(gòu)造函數(shù)有兩個(gè)參數(shù)分別是nanem和age,然后他在調(diào)用本類的主構(gòu)造函數(shù)的時(shí)候直接實(shí)例化了主構(gòu)造函數(shù)中的sno和grade兩個(gè)參數(shù),然后將自己的name和age傳給了調(diào)用了的主構(gòu)造函數(shù) constructor(name: String, age: Int) : this("", 0, name, age){ } //次構(gòu)造函數(shù)2:不接收任何的參數(shù),然后沒有直接調(diào)用本類的主構(gòu)造函數(shù),而是調(diào)用了次構(gòu)造函數(shù)1,相當(dāng)于間接調(diào)用了本類的主構(gòu)造函數(shù) constructor() : this("張三", 18) }
當(dāng)Student類通過上述方式編寫之后,我們就可以使用主構(gòu)造函數(shù)或者此構(gòu)造函數(shù)對(duì)其進(jìn)行實(shí)例化了,那么對(duì)Student類進(jìn)行實(shí)例化的方式就有了三種
//使用主構(gòu)造函數(shù)對(duì)Student類進(jìn)行實(shí)例化 val student1 = Student("123", 1, "張三", 18) //使用次構(gòu)造函數(shù)1對(duì)Student進(jìn)行實(shí)例化 val student2 = Student("張三", 18) //使用次構(gòu)造函數(shù)2對(duì)Student進(jìn)行實(shí)例化 val student3 = Student()
還有一種比較特殊的情況,類中只包含次構(gòu)造函數(shù),沒有主構(gòu)造函數(shù),這種情況雖然少見,但是在Kotlin當(dāng)中是允許的,當(dāng)一個(gè)類沒有顯示的定義主構(gòu)造函數(shù)但是定義了次構(gòu)造函數(shù)的時(shí)候,它就是沒有主構(gòu)造函數(shù)的
class Student : Preson { constructor(name: String, age: Int) : super(name, age) { } }
在上面的代碼中,首先Student類后i按沒有顯示的定義主構(gòu)造函數(shù),同時(shí)又定義了次構(gòu)造函數(shù),所以Student類是沒有主構(gòu)造函數(shù)的,因?yàn)闆]有主構(gòu)造函數(shù),所以就不牽扯子類的主構(gòu)造函數(shù)調(diào)用父類的主構(gòu)造函數(shù)這一說,所以說Person類的后面沒有加()
另外,由于沒有主構(gòu)造函數(shù),此構(gòu)造函數(shù)只能直接調(diào)用父類的構(gòu)造函數(shù),所以在次構(gòu)造函數(shù)在調(diào)用方法的時(shí)候?qū)his關(guān)鍵字換成了super關(guān)鍵字
接口
Kotlin當(dāng)中的接口和java當(dāng)中的接口幾乎完全是一致的,接口是用于多態(tài)編程的重要組成部分,java是單繼承語(yǔ)言,但是可以實(shí)現(xiàn)多個(gè)接口,Kotlin中也同樣是這樣
定義一Study接口
interface Study { fun readBooks() fun doHomeWork() }
Student實(shí)現(xiàn)Study接口
class Student : Person(), Study{ var sno = "" var grade = 0 override fun readBooks() { println("讀書") } override fun doHomeWork() { println("做作業(yè)") } }
在java當(dāng)中繼承使用的關(guān)鍵字是extends,實(shí)現(xiàn)使用的是impls關(guān)鍵字,而在Kotlin當(dāng)中繼承和實(shí)現(xiàn)統(tǒng)一使用的是 : ,如果即做了繼承又進(jìn)行了實(shí)現(xiàn),使用,進(jìn)行隔開
在上面的代碼中,Student實(shí)現(xiàn)了Study接口,那么他就必須要實(shí)現(xiàn)Study中的兩個(gè)方法,在Kotlin當(dāng)中使用override關(guān)鍵字來重寫父類或者實(shí)現(xiàn)接口中的方法.
多態(tài)編程的特性
fun main() { val student = Student() doStudy(student) } fun doStudy(study: Study) { study.readBooks() study.doHomeWork() }
因?yàn)镾tudent實(shí)現(xiàn)了Study接口,在doStudy方法中,需要傳遞的參數(shù)是Study類型,所以也可以傳遞一個(gè)Student的實(shí)例
還有一點(diǎn)就是在Kotlin當(dāng)中可以對(duì)接口中的抽象方法進(jìn)行默認(rèn)的實(shí)現(xiàn)
interface Study { fun readBooks() //在Kotlin的接口中可以對(duì)方法進(jìn)行默認(rèn)實(shí)現(xiàn) fun doHomeWork() { println("do homework") } }
如果接口中的一個(gè)函數(shù),擁有了函數(shù)體,這個(gè)函數(shù)中的內(nèi)容就是他的默認(rèn)實(shí)現(xiàn),現(xiàn)在一個(gè)類去實(shí)現(xiàn)Study接口的時(shí)候,只會(huì)強(qiáng)制要求實(shí)現(xiàn)readBooks方法,而doHomeWork方法可以自由選擇進(jìn)行實(shí)現(xiàn),不是先是就會(huì)自動(dòng)使用默認(rèn)的實(shí)現(xiàn)邏輯
訪問修飾符
在java當(dāng)中的訪問控制符一種有四種:public,private,protected,defaule(什么都不寫)
在Kotlin當(dāng)中也有四種訪問控制符:public,private,protected和internal,需要使用那種修飾符號(hào)的時(shí)候直接在fun關(guān)鍵字前面進(jìn)行添加即可
private修飾符在java和Kotlin當(dāng)中的作用是一摸一樣的,都表示對(duì)當(dāng)前類的內(nèi)部進(jìn)行可見
public修飾符作用雖然也是一致的,表示對(duì)所有的類都可見,但是在java中default是默認(rèn)項(xiàng),但是在Kotlin當(dāng)中public才是默認(rèn)項(xiàng)
protected關(guān)鍵字在java中表示在該類和該類的子類以及同一包中可見,但是在Kotlin當(dāng)中值表示對(duì)該類和子類可見
Kotlin當(dāng)中拋棄了java中的defualt權(quán)限(同一個(gè)包路徑下可見)而是引入了一種新的權(quán)限internal
internal表示在同一個(gè)模塊中的類可見.比如我們開發(fā)一個(gè)模塊給別人用,但是有一些函數(shù)只允許在模塊的內(nèi)部進(jìn)行調(diào)用,不想暴露給外部,那么就可以將這些函數(shù)用internal關(guān)鍵字進(jìn)行修飾
數(shù)據(jù)類和單例
數(shù)據(jù)類通常需要重寫equals,hashCode,toString方法,其中equals方法用于判斷兩個(gè)數(shù)據(jù)是否相等,hashCode方法是equals方法的配套方法,toString方法用來打印更為清晰的日志,否則數(shù)據(jù)打印出來就是一串地址
在java當(dāng)中就要一一的實(shí)現(xiàn)這些方法
但是在Kotlin當(dāng)中,只需要使用date關(guān)鍵字就可以解決
data class Cellphone(val brand: String, val price: Int)
在上面這行代碼中,我就定義了一個(gè)數(shù)據(jù)類,當(dāng)一個(gè)date關(guān)鍵字放在class前面的時(shí)候,就表明自己希望這個(gè)類是一個(gè)數(shù)據(jù)類,Kotlin會(huì)根據(jù)主構(gòu)造函數(shù)中的參數(shù)幫這個(gè)類將equals,hashCode,toString方法進(jìn)行了重寫,另外當(dāng)一個(gè)類中沒有任何代碼時(shí)候,類的{}可以進(jìn)行省略
接下來就是單例類,單例模式是一種基礎(chǔ)的設(shè)計(jì)模式,當(dāng)我們?cè)陂_發(fā)的過程中,希望某個(gè)類在全局最多只能有一個(gè)實(shí)例,這樣就可以使用單例模式,單例模式使用java語(yǔ)言的編寫方式有很多種,雖然簡(jiǎn)單,但是在Kotlin中還有更加簡(jiǎn)單的方法
在Kotlin當(dāng)中創(chuàng)建一個(gè)單例類十分簡(jiǎn)單,只需要將class關(guān)鍵字改成object關(guān)鍵字即可,在創(chuàng)建類的時(shí)候直接選擇object不要選擇class即可
object Singleton { }
現(xiàn)在Singleton就已經(jīng)是一個(gè)單例類,我們可以直接在這個(gè)類當(dāng)中編寫需要的函數(shù),比如加上一個(gè)singletonTest方法
object Singleton { fun singletonTest() { println("this is a singleTon.") } }
可以看到在Kotlin當(dāng)中我們不需要私有化構(gòu)造函數(shù),也不需要提供getInstance()這樣的靜態(tài)方法,只需要將class關(guān)鍵字修改該成為object關(guān)鍵字即可
上述代碼在調(diào)用的時(shí)候直接使用Singleton.singletonTest()即可,這種寫法看上去像是靜態(tài)方法調(diào)用,但是實(shí)際上Kotlin在背后自動(dòng)幫我們創(chuàng)建了一個(gè)Singleton類的實(shí)例
到此這篇關(guān)于Kotlin面向?qū)ο笾R(shí)點(diǎn)講解的文章就介紹到這了,更多相關(guān)Kotlin面向?qū)ο髢?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android studio logcat 無篩選 顯示全部日志 無應(yīng)用包名區(qū)分方式
這篇文章主要介紹了android studio logcat 無篩選 顯示全部日志 無應(yīng)用包名區(qū)分方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04Android app啟動(dòng)時(shí)黑屏或者白屏的原因及解決辦法
這篇文章主要介紹了Android app啟動(dòng)時(shí)黑屏或者白屏的原因及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-09-09Android實(shí)現(xiàn)在子線程中更新Activity中UI的方法
這篇文章主要介紹了Android實(shí)現(xiàn)在子線程中更新Activity中UI的方法,涉及Android線程與activity操作的相關(guān)技巧,需要的朋友可以參考下2016-04-04Android 自定義View實(shí)現(xiàn)任意布局的RadioGroup效果
這篇文章主要介紹了Android 自定義View實(shí)現(xiàn)任意布局的RadioGroup,需要的朋友可以參考下2018-11-11Android實(shí)現(xiàn)雷達(dá)View效果的示例代碼
這篇文章主要介紹了Android實(shí)現(xiàn)雷達(dá)View效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Android自定義ViewGroup打造各種風(fēng)格的SlidingMenu
這篇文章主要介紹了Android自定義ViewGroup打造各種風(fēng)格的SlidingMenu的相關(guān)資料,需要的朋友可以參考下2016-02-02Android自定義可左右滑動(dòng)和點(diǎn)擊的折線圖
這篇文章主要為大家詳細(xì)介紹了Android自定義可左右滑動(dòng)和點(diǎn)擊的折線圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04