網(wǎng)站首頁 編程語言 正文
類和對象
創(chuàng)建一個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對象,對字符進(jìn)行賦值,調(diào)用類中的方法
fun main() {
val p = Person();
p.name = "張三"
p.age = 10
p.eat()
}
注意在Kotlin當(dāng)中創(chuàng)建對象不需要new關(guān)鍵字
繼承和構(gòu)造函數(shù)
- 繼承是面向?qū)ο蟮囊淮筇匦?/li>
- 在Kotlin中和java不同的是,在Koitlin中任何一個非抽象類都是默認(rèn)不可以被繼承的,就相當(dāng)于在java中給一個類加上了final關(guān)鍵字
- 因?yàn)樵谝槐久麨镋ffective Java中的書明確提到,如果一個類不是專門為了繼承而設(shè)計(jì)的,那么他就應(yīng)該加上final聲明,禁止它可以被繼承,這個屬于就是編程規(guī)范了
- 在Kotlin當(dāng)中的抽象類和java并沒有什么區(qū)別
- 在Kotlin中如果想要一個類可以被繼承,只需要在這個類的前面加上open關(guān)鍵字即可
- 如果一個類要繼承一個類的話,在java當(dāng)中使用的是extends關(guān)鍵字,在Kotlin當(dāng)中使用的是 : 這個關(guān)鍵字,而且父類不僅僅要寫出類名還要帶上一對括號
class Student : Person() {
var sno = ""
var grade = 0
}
Kotlin中類的主構(gòu)造函數(shù)
每個類都會默認(rèn)有一個不帶參數(shù)的主構(gòu)造函數(shù),但是我們也可以顯示的給他指定參數(shù),主構(gòu)造函數(shù)的特點(diǎn)是沒有函數(shù)體,直接定義在類名的后面即可
class Student(val sno: String, val grade: Int) {
}
上面這行代碼就表示Student的主構(gòu)造函數(shù)有兩個參數(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í)行一些代碼邏輯
那么子類在繼承父類的時候,為什么父類名后面要跟上一對括號呢,原因是,子類在繼承父類的時候,子類的構(gòu)造函數(shù)必須調(diào)用父類的構(gòu)造函數(shù),所以子類的主構(gòu)造函數(shù)調(diào)用父類的那個構(gòu)造函數(shù),就是由這個()來進(jìn)行指定的.
class Student : Person() {
var sno = ""
var grade = 0
}
在這里Person類后面一對空括號表示Student類的主構(gòu)造函數(shù)在初始化的時候會調(diào)用Person類的無參構(gòu)造函數(shù)
次構(gòu)造函數(shù):在Kotlin當(dāng)中,每一個類只能有一個主構(gòu)造函數(shù),但是可以有多個次構(gòu)造函數(shù),次構(gòu)造函數(shù)也可以實(shí)例化一個類,區(qū)別就是主構(gòu)造函數(shù)沒有函數(shù)體,次構(gòu)造函數(shù)有函數(shù)體
Kotlin規(guī)定,在一個類當(dāng)中如果同時存在主構(gòu)造函數(shù)和次構(gòu)造函數(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òu)造函數(shù)有兩個參數(shù)分別是nanem和age,然后他在調(diào)用本類的主構(gòu)造函數(shù)的時候直接實(shí)例化了主構(gòu)造函數(shù)中的sno和grade兩個參數(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ù)對其進(jìn)行實(shí)例化了,那么對Student類進(jìn)行實(shí)例化的方式就有了三種
//使用主構(gòu)造函數(shù)對Student類進(jìn)行實(shí)例化
val student1 = Student("123", 1, "張三", 18)
//使用次構(gòu)造函數(shù)1對Student進(jìn)行實(shí)例化
val student2 = Student("張三", 18)
//使用次構(gòu)造函數(shù)2對Student進(jìn)行實(shí)例化
val student3 = Student()
還有一種比較特殊的情況,類中只包含次構(gòu)造函數(shù),沒有主構(gòu)造函數(shù),這種情況雖然少見,但是在Kotlin當(dāng)中是允許的,當(dāng)一個類沒有顯示的定義主構(gòu)造函數(shù)但是定義了次構(gòu)造函數(shù)的時候,它就是沒有主構(gòu)造函數(shù)的
class Student : Preson {
constructor(name: String, age: Int) : super(name, age) {
}
}
在上面的代碼中,首先Student類后i按沒有顯示的定義主構(gòu)造函數(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)用方法的時候?qū)his關(guān)鍵字換成了super關(guān)鍵字
接口
Kotlin當(dāng)中的接口和java當(dāng)中的接口幾乎完全是一致的,接口是用于多態(tài)編程的重要組成部分,java是單繼承語言,但是可以實(shí)現(xiàn)多個接口,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中的兩個方法,在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類型,所以也可以傳遞一個Student的實(shí)例
還有一點(diǎn)就是在Kotlin當(dāng)中可以對接口中的抽象方法進(jìn)行默認(rèn)的實(shí)現(xiàn)
interface Study {
fun readBooks()
//在Kotlin的接口中可以對方法進(jìn)行默認(rèn)實(shí)現(xiàn)
fun doHomeWork() {
println("do homework")
}
}
如果接口中的一個函數(shù),擁有了函數(shù)體,這個函數(shù)中的內(nèi)容就是他的默認(rèn)實(shí)現(xiàn),現(xiàn)在一個類去實(shí)現(xiàn)Study接口的時候,只會強(qiáng)制要求實(shí)現(xiàn)readBooks方法,而doHomeWork方法可以自由選擇進(jìn)行實(shí)現(xiàn),不是先是就會自動使用默認(rèn)的實(shí)現(xiàn)邏輯
訪問修飾符
在java當(dāng)中的訪問控制符一種有四種:public,private,protected,defaule(什么都不寫)
在Kotlin當(dāng)中也有四種訪問控制符:public,private,protected和internal,需要使用那種修飾符號的時候直接在fun關(guān)鍵字前面進(jìn)行添加即可
private修飾符在java和Kotlin當(dāng)中的作用是一摸一樣的,都表示對當(dāng)前類的內(nèi)部進(jìn)行可見
public修飾符作用雖然也是一致的,表示對所有的類都可見,但是在java中default是默認(rèn)項(xiàng),但是在Kotlin當(dāng)中public才是默認(rèn)項(xiàng)
protected關(guān)鍵字在java中表示在該類和該類的子類以及同一包中可見,但是在Kotlin當(dāng)中值表示對該類和子類可見
Kotlin當(dāng)中拋棄了java中的defualt權(quán)限(同一個包路徑下可見)而是引入了一種新的權(quán)限internal
internal表示在同一個模塊中的類可見.比如我們開發(fā)一個模塊給別人用,但是有一些函數(shù)只允許在模塊的內(nèi)部進(jìn)行調(diào)用,不想暴露給外部,那么就可以將這些函數(shù)用internal關(guān)鍵字進(jìn)行修飾
數(shù)據(jù)類和單例
數(shù)據(jù)類通常需要重寫equals,hashCode,toString方法,其中equals方法用于判斷兩個數(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)
在上面這行代碼中,我就定義了一個數(shù)據(jù)類,當(dāng)一個date關(guān)鍵字放在class前面的時候,就表明自己希望這個類是一個數(shù)據(jù)類,Kotlin會根據(jù)主構(gòu)造函數(shù)中的參數(shù)幫這個類將equals,hashCode,toString方法進(jìn)行了重寫,另外當(dāng)一個類中沒有任何代碼時候,類的{}可以進(jìn)行省略
接下來就是單例類,單例模式是一種基礎(chǔ)的設(shè)計(jì)模式,當(dāng)我們在開發(fā)的過程中,希望某個類在全局最多只能有一個實(shí)例,這樣就可以使用單例模式,單例模式使用java語言的編寫方式有很多種,雖然簡單,但是在Kotlin中還有更加簡單的方法
在Kotlin當(dāng)中創(chuàng)建一個單例類十分簡單,只需要將class關(guān)鍵字改成object關(guān)鍵字即可,在創(chuàng)建類的時候直接選擇object不要選擇class即可
object Singleton {
}
現(xiàn)在Singleton就已經(jīng)是一個單例類,我們可以直接在這個類當(dāng)中編寫需要的函數(shù),比如加上一個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)用的時候直接使用Singleton.singletonTest()即可,這種寫法看上去像是靜態(tài)方法調(diào)用,但是實(shí)際上Kotlin在背后自動幫我們創(chuàng)建了一個Singleton類的實(shí)例
原文鏈接:https://blog.csdn.net/weixin_45809829/article/details/127761439
相關(guān)推薦
- 2022-09-29 關(guān)于React動態(tài)修改元素樣式的三種方式_React
- 2022-11-08 Python?運(yùn)算符Inplace?與Standard?_python
- 2022-10-14 Redis緩存擊穿解決方案之互斥鎖
- 2022-06-09 Qt中QPainter與坐標(biāo)的使用_C 語言
- 2022-08-19 Mac上Chrome瀏覽器快捷鍵匯總
- 2022-09-23 Shell腳本函數(shù)傳遞參數(shù)的實(shí)現(xiàn)方法_linux shell
- 2022-01-20 解決:npm install 報錯 npm ERR code ERESOLVE npm ERR ER
- 2023-10-14 uniapp 將base64字符串保存為圖片、Word、Excel、音頻、視頻等文件
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支