1、Kotlin 繼承open關鍵字
//TODO Kotlin 基礎與重載的open關鍵字
//所有的類默認是final修飾的,不能被繼承與Java相反
//加open相當於移除final
open class Person(val name:String){
private fun showName() = "人類的名字是[$name]"
//所有的函數默認也是final修飾,不能被重寫
open fun myPrintlin() = println(showName())
}
class Student(val subName:String) : Person(subName){
private fun showName() = "子類的姓名是[$subName]"
override fun myPrintlin() = println(showName())
}
fun main() {
val person:Person = Student("張三")
person.myPrintlin()
}
2、Kotlin 類型轉換
//TODO Kotlin 類型轉換
import java.io.File
//所有的類默認是final修飾的,不能被繼承與Java相反
//加open相當於移除final
open class Person(val name: String) {
fun showName() = "人類的名字是[$name]"
//所有的函數默認也是final修飾,不能被重寫
open fun myPrintlin() = println(showName())
}
class Student(val subName: String) : Person(subName) {
fun showName2() = "子類的姓名是[$subName]"
override fun myPrintlin() = println(showName2())
}
fun main() {
val p: Person = Student("王五")
p.myPrintlin()
println(p is Person)
println(p is Student)
println(p is File)
//is +as
if (p is Student) {
(p as Student).myPrintlin()
}
if (p is Person) {
// (p as Person).myPrintlin()
println((p as Person).showName())
}
}
3、Kotlin智能轉換
import java.io.File
//TODO Kotlin 智能類型轉換
//所有的類默認是final修飾的,不能被繼承與Java相反
//加open相當於移除final
open class Person(val name:String){
fun showName() = "人類的名字是[$name]"
//所有的函數默認也是final修飾,不能被重寫
open fun myPrintlin() = println(showName())
fun methodPerson() = println("我是父類的方法...")
}
class Student(val subName:String) : Person(subName){
fun showName2() = "子類的姓名是[$subName]"
override fun myPrintlin() = println(showName2())
fun methodStudent() = println("我是子類的方法...")
}
fun main() {
val p:Person = Student("王五")
//is +as
(p as Student).methodStudent()
//根據上面P as 說明已經轉過的類型,下面可以直接調用子類的方法
p.methodStudent()
}
4、Kotlin 中Any類
//TODO Kotlin Any超類 相當於Java 的Object
//在Kotlin中類隱式繼承了Any(),不寫,默認也有
//Any 設計中,只提供標準,看不到實現
class obj1:Any()
fun main() {
println(obj1().toString())
}
只提供標準,不會進行實現
5、Kotlin Object
object KtBase {
/*
object 類 背後做了什麼?
public static final KtBase INSTANCE;
private KtBase(){} //主構造廢除一樣的效果
public final void show(){
String var1 = "我是show函數";
...
System.out.println(var1)
}
//這個區域是object不同點
static{
KtBase var0 = new KtBase();
INSTANCE = var0;
String var1 = "KtBase init..."
System.out.println(var0)
}
*/
init {
println("KtBase init...")
}
fun show() = println("我是show函數")
}
fun main() {
// object KtBase既是單例的實類,也是類名
//小結: 既然是單例的實例,又是類名,只有一個創建,這就是典型的單例
println(KtBase) // 背後代碼println(KtBase.INSTANCE)
println(KtBase)
println(KtBase)
//不需要帶() KTBase.INSTANCE
println(KtBase.show())
}
INSTANCE在靜態代碼塊里進行初始化
6、Kotlin對象表達式
open class KtBase {
open fun add(info: String) = println("add:$info")
open fun del(info: String) = println("del:$info")
}
//具名方式實現
class KTBase1 : KtBase() {
override fun add(info: String) {
// super.add(info)
println("我是具名對象add:$info")
}
override fun del(info: String) {
// super.del(info)
println("我是具名對象del:$info")
}
}
fun main() {
//匿名對象表達式
val p = object : KtBase() {
override fun add(info: String) {
// super.add(info)
println("我是匿名對象add:$info")
}
override fun del(info: String) {
// super.del(info)
println("我是匿名對象del:$info")
}
}
p.add("李元霸")
p.del("李連杰")
//具名方式實現
val p2 = KTBase1()
p2.add("李元霸")
p2.del("李連杰")
//java 接口方式
val p3 = object :Runnable {
override fun run() {
println("Runnable run ..")
}
}
p3.run()
//java最簡潔方式
val p4 = Runnable {
println("Runnable run2 ..")
}
p4.run()
}
7、Kotlin 伴生對象
//TODO Kotlin 伴生對象
class KtBase {
//伴生對象由來:Kotlin中沒有static靜態,伴生很大程度上和Java的這種static靜態差不多
companion object {
val info = "testInfo"
fun showInfo() = println("顯示:$info")
}
/* companion object{} 背後邏輯
private static final String info = "testInfo";
public static final KtBase.Companion campoanion = new Companion();
*/
}
//伴生對象只會初始化一次
fun main() {
//背後代碼 KtBase.Companion.getInfo
println(KtBase.info)
//背後代碼 KtBase.Companion.showInfo()
KtBase.showInfo()
//new KtBase() ,無論構建多少次,伴生對象只有一次
KtBase()
KtBase()
KtBase()
KtBase()
}
8、Kotlin 內部類inner與嵌套類
//TODO Kotlin 嵌套類 和內部類
//內部類特點 :內部類能訪問外部的類
//外部的類 能訪問內部的類,加inner修飾符
class Body(_bodyInfo: String) {
val bodyInfo = _bodyInfo
//默認情況下:內部類不能訪問外部類,要加修飾符稱為內部類,才可以訪問外部類
inner class Heart {
fun run() = println("心臟訪問身體信息:$bodyInfo")
}
inner class Kidney {
fun work() = println("腎臟訪問身體信息:$bodyInfo")
}
inner class Hand {
inner class LeftHand {
fun work() = println("左手訪問身體信息:$bodyInfo")
}
inner class RightHand {
fun work() = println("右手腎臟訪問身體信息:$bodyInfo")
}
}
}
//嵌套類,默認情況下是嵌套類
//嵌套類特點:外部的類 能訪問內部的類 ,嵌套類不能訪問內部外部類的成員
class Outer {
val info = "ok"
fun show() {
Nested().output()
}
class Nested {
fun output() = println()
}
}
fun main() {
//內部類
Body("isOk").Heart().run()
Body("isOk").Hand().LeftHand().work()
//嵌套類
Outer.Nested().output()
}
9、Kotlin數據類data 修飾
//普通類
//生成的只有普通變量,set get方法
class ResponseResultBean(var msg: String, var code: Int, var data: String)
//數據量 ,一般情況下用於javaBean
//除了生成普通變量,set get方法,還有hashCode,equals(),解構操作,toString()
//數據類生成的方法更多
data class ResponseResultBean2(var msg: String, var code: Int, var data: String)
fun main() {
//val (v1,v2,v3) = list
//ResponseResultBean@610455d6 ,調用Any.toString(),只提供標準,windows實現列印的
println(ResponseResultBean("loginSuccess", 200, "登錄成功的數據"))
//data 數據類,額外生成toString(),重寫了父類的toString()函數
//ResponseResultBean2(msg=loginSuccess, code=200, data=登錄成功的數據)
println(ResponseResultBean2("loginSuccess", 200, "登錄成功的數據"))
println()
// == 值得比較,===引用的比較
// == Any的父類 由平台實現,由兩個對象引用進行比較,所以返回false
println(
ResponseResultBean("loginSuccess", 200, "登錄成功的數據") ==
ResponseResultBean("loginSuccess", 200, "登錄成功的數據")
)
// == Any的父類 ,會重寫父類的equals,進行的值得比較,返回為true
println(
ResponseResultBean2("loginSuccess", 200, "登錄成功的數據") ==
ResponseResultBean2("loginSuccess", 200, "登錄成功的數據")
)
}
Kotlin 數據類data使用場景
1:伺服器請求回來的響應 JavaBean 基本上可以使用數據類
2、條件類至少必須有一個參數的主構造函數
3、數據類必須有參數, var val 的參數
4、 數據類不能使用abstract ,不能open saled ,inner等等修飾, 數據類只做數據載入的事情
5、需求; 比較,copy. toString,結構等豐富功能,可以使用數據類
10、Kotlin copy函數
//TODO Kotlin copy函數
data class KtBase(var name: String,var age :Int){
var coreInfo:String = ""
//次構造
constructor(name: String) :this(name,99){
println("次構造被調用")
coreInfo = "增加非常核心的內容信息"
}
override fun toString(): String {
return "toString name:$name,age:$age,coreInfo:$coreInfo"
}
}
/*
//默認生成的toString ,hashCode(),equals(),只管主構造,不管次構造
@NotNull
public String toString() {
return "KtBase(name=" + this.name + ", age=" + this.age + ")";
}
*/
fun main() {
val p1 = KtBase("李元霸")//調用次構造初始化
println(p1)
val newP2 = p1.copy("李連杰",78)
println(newP2)
// copy toString hashCode equals
//注意事項:使用copy時,只考慮主構造,copy調用的也是主構造, 必須考慮次構造內容
}
11、Kotlin 解構函數
//TODO Kotlin 解構聲明 component
//數據類自己就解構
class Student(var name:String,var age:Int,var sex:Char){
//注意:順序必須是component1 ,component2 ,component3 和成員一一對應
operator fun component1() = name
operator fun component2() = age
operator fun component3() = age
}
/*
//默認生成的toString ,hashCode(),equals(),只管主構造,不管次構造
@NotNull
public String toString() {
return "KtBase(name=" + this.name + ", age=" + this.age + ")";
}
*/
data class Student2(var name:String,var age: Int,var sex: Char)
fun main() {
val(name,age,sex) = Student("李四",89,'男')
println("普通類 解構後:name:$name,age:$age,sex:$sex")
val(name1,age1,sex1) = Student2("李四",89,'男')
println("數據類 解構後:name:$name1,age:$age1,sex:$sex1")
val (_,age2,_) = Student("李四",89,'男')
println("數據類 解構後:age:$age2")
}
12、Kotlin 運算符重載
//TODO Kotlin 運算符重載
class AddClass(number1:Int,number2:Int)
data class AddClass2(var number1: Int,var number2: Int){
operator fun plus(p1:AddClass2) : Int{
return (number1+p1.number1) + (number2 + p1.number2)
}
}
fun main() {
//運算符重載 C++ 里 +
//KT中plus代表+
// AddClass2(1,1)+AddClass2(2,2)
println( AddClass2(1,1)+AddClass2(2,2))
}
查看所有可用的運算符重載
13、Kotlin 中枚舉
//枚舉也是一個class
enum class Week {
星期一,
星期二,
星期三,
星期四,
星期五,
星期六,
星期日
}
//枚舉類學習
fun main() {
//枚舉的值等價於枚舉本身
println(Week.星期一)
println(Week.星期五)
println(Week.星期二 is Week)
}
14、Kotlin中枚舉詳細使用
//TODO Kotlin 枚舉類詳細使用
data class LimbsInfo(var LimbsInfo:String,var length: Int){
fun show(){
println("${LimbsInfo}的長度是:$length")
}
}
//枚舉是一個class,就是為了枚舉有更好的功能
enum class Limbs(private var limbsInfo: LimbsInfo){
LETF_HAND(LimbsInfo("左手",88)),//左手
RIGHT_HAND(LimbsInfo("右手",88)),//右手
LETF_FOOT(LimbsInfo("左腳",88)),//左腳
RIGHT_FOOT(LimbsInfo("右腳",88))//右腳
;//結束枚舉值
// 1、WEEK() 這時候再定義單調的枚舉值,就報錯了,必須所有枚舉值,保持一致效果
//2、枚舉主構造的參數必須和枚舉(參數) 保持一致
fun show() = "四肢是:${limbsInfo.LimbsInfo}的長度是:${limbsInfo.length}"
fun updateData(limbsInfo: LimbsInfo){
println("更新前的數據是:${this.limbsInfo}}")
this.limbsInfo.LimbsInfo = limbsInfo.LimbsInfo
this.limbsInfo.length = limbsInfo.length
println("更新後的數據是:${this.limbsInfo}}")
}
}
//枚舉類學習
fun main() {
//顯示枚舉值
//一般不會這麼用
/*println(Limbs().show())
println(Limbs.show())*/
//一般用法如下
println(Limbs.LETF_HAND.show())
println(Limbs.RIGHT_HAND.show())
println(Limbs.LETF_FOOT.show())
println(Limbs.RIGHT_FOOT.show())
//更新枚舉值
Limbs.RIGHT_HAND.updateData(LimbsInfo("右手2",99))
Limbs.LETF_FOOT.updateData(LimbsInfo("左腳2",99))
}
//TODO Kotlin 枚舉類詳細使用
enum class Exam{
Eraction1,//分數差
Eraction2,//分數及格
Eraction3,//分數良好
Eraction4,//分數優秀
;//枚舉結束
//得到優秀學生的名字 ,枚舉類做到此需求,很麻煩 //引出密封類
var studentName:String? = null
}
class Teacher(private val exam: Exam){
fun show() :String=
when(exam){
Exam.Eraction1 -> "該學生分數很差"
Exam.Eraction2 -> "該學生分數及格"
Exam.Eraction3 -> "該學生分數良好"
Exam.Eraction4 -> "該學生分數優秀"
//else -> 由於show函數是使用枚舉類型來判斷處理,這個屬於代數數據類型,不需要寫else
//因為when表達式很明確,就這四種類型,不會出現其他,所以可以不寫
}
}
//枚舉類學習
fun main() {
println(Teacher(Exam.Eraction1).show())
println(Teacher(Exam.Eraction3).show())
}
15、Kotlin密封類
import sun.security.util.Length
import kotlin.math.E
//TODO Kotlin 密封類詳細使用
//密封類成員 必須有類型且繼承本類 sealed
sealed class Exam {
//不需要任何成員,寫成object
object Eraction1 : Exam()//分數差
object Eraction2 : Exam()//分數及格
object Eraction3 : Exam()//分數良好
class Eraction4(val studentName2: String) : Exam()//分數優秀
//得到優秀學生的名字 ,枚舉類做到此需求,很麻煩 //引出密封類
var studentName: String? = null
}
class Teacher(private val exam: Exam) {
fun show(): String =
when (exam) {
is Exam.Eraction1 -> "該學生分數很差"
is Exam.Eraction2 -> "該學生分數及格"
is Exam.Eraction3 -> "該學生分數良好"
is Exam.Eraction4 -> "該學生分數優秀:該學生的姓名是:${(this.exam as Exam.Eraction4).studentName2}"
else -> " error"
}
}
//枚舉類學習
fun main() {
println(Teacher(Exam.Eraction1).show())
println(Teacher(Exam.Eraction2).show())
println(Teacher(Exam.Eraction3).show())
println(Teacher(Exam.Eraction4("李四")).show())
println(Teacher(Exam.Eraction4("王五")).show())
println(Exam.Eraction1 === Exam.Eraction1)
println(Exam.Eraction4("AAA") === Exam.Eraction4("AAA")) //class 有兩個不同的對象是false,不是object
}
作者:胖胖狼
連結:https://juejin.cn/post/7101308364562366471