二、面向对象
1、类以及接口
1、 属性没有默认值必须赋值。成员是默认全局可见。
2、可带有属性和默认方法的接口
我们在给接口添加新的方法的时候,之前继承过该接口的类则不需要实现新添加的方法
接口中的属性其实是使用方法来实现的,所以不能给默认值,如果要给默认值可以通过方法来实现
interface Car{
val speed:Int
get()=100
}
在实现该接口的类中必须得对属性进行初始化。
2、构造函数
1、解决了java里的构造方法过多的问题
class Bird(val weight: Double = 0.00 , val age: Int = 0 , val color: String = "blue")
//可以省略{} 一行搞定
val bird1 = Bird(color = "black")
val bird2 = Bird(weight = 1000.00 , color = "black")
2、init语法块,它属于构造函数的一部分,构造函数只能给参数赋值,要想在初始化的时候进行其他的初始操作就需要用到init块,
当没有var或者val 的时候构造方法的参数可以再init块里直接使用
构造方法的参数还可以在初始化属性成员时调用,除此之外其他情况都不能调用。
init{
} 可以有多个会按照从上往下的定义顺序执行。
3、延迟初始化 by lazy lateinit
by lazy用于 val 的声明,其实是一种委托
lateinit主要用于 var的声明,然而他不能作用于基本数据类型,Int,Long等,用Integer这种包装类进行替代即可。
4、主从构造方法
主构造方法:在类外部定义的构造方法
从构造方法:用constructor创建的方法,可以有多个从构造方法。
通过this关键字来调用要委托的构造方法,如果一个类存在主构造方法,那么从构造方法都要直接或者间接的委托给他,例如:
3、访问控制原则
1、限制修饰符 (默认是final的)
加上open修饰符的类或者方法才可以被继承或者重写,继承用符号冒号:表示,没有java的extends;
abstract修饰符跟java用法一样
2、可见性修饰符
1、java中的默认修饰符是default,kotlin中的默认修饰符是public
2、java中只允许内部类用private修饰,而kotlin都可以
3、kotlin有internal修饰符,模块内访问,
4、protected 在java允许包、类、子类可以访问,在kotlin只允许类及子类可以访问。
4、多继承问题
1、如果是多继承实现的方法冲突,可以用super<T>.方法去指定实现哪个接口的方法。
2、不要忘记override
3、内部类解决多继承
1、 内部类需要类类的前边加上 inner字段
2、内部类和嵌套类的区别?内部类包含外部类实例的引用,可以使用外部类的属性,嵌套类则没有,也不能访问属性。
3、用内部类解决多继承,可以在一个类内部定义多个内部类,每个内部类的实例都有自己的独立的状态,他们与外部对象的信息互相独立。
4、用委托代替多继承
委托用法跟接口类似,接口里不能有复杂的逻辑,委托的类里可以有,另外委托还可以更加直观的直接调用委托类里的方法
示例:
interface Fly{
fly();
}
interface Eat{
eat();
}
open class Flyer :Fly{
override fun fly(){
//fly的逻辑
}
}
open class Eater:Eat{
override fun eat(){
//Eat的逻辑
}
}
class Bird(flyer:Flyer ,eater:Eater):Fly by flyer,Eat by eater{};
//调用
Bird b= new Bird(Flyer(),Eater());
b.eat();
b.fly();
Bird就可以直接调用委托类的 eat和fly方法了。
5、数据类
1、用data class 修饰创建数据类,省去getter和setter代码,一行搞定,使用方式类似Map
data class Data(var param:String){}
2、componentN与解构
componentN就是数据类的属性值,component1就是第一个参数的值以此类推,从1开始。
数据类中的解构基于componentN函数,如果自己不声明componentN函数,那么就会默认主构造函数的参数来生成具体个数的componentN函数 ,与从构函数里的参数无关,要想用从构函数里的参数实现解构,就得自己实现componentN函数,用operator关键字修饰。如:
data class Data(var param:String){
var param2
operator fun component2():Int{
return this.param2
}
constructor Data(param:String,param2:Int):this(param){
this.param2=param2
}
}
//调用
var data = Data("nihao",1)
var (param,param2)=data//这样就可以获取到Data数据类对象里的参数的值了
kotlin还可以对数组进行解构,不过最多允许5个变量
var str= "1,2,3"
val (str1,str2,str3)=str.split(",")
除了数组外还提供了其他的数据类如Pair (二元数组)Triple(三元数组),我们可以按照属性的顺序获取属性的值
val (str1,str2)= Pair("1",2) str1="1" str2=2
6、数据类的约定与使用
1、数据类必须至少有一个构造方法,构造方法至少有一个参数
2、数据类的参数强制使用var或者val声明与普通类的不同
3、data class 前不能用abstract open sealed inner修饰
6、Kotlin用object替代static实现更多的功能
1、伴生对象
伴生对象是companion object 两个关键字创建的语法,意为伴随某个类而生的对象,跟static一样全局只有一个单例,它申明在类的内部,切在类加载时会被初始化,它能实现除所有static的功能外的其他功能。
结构
class Data{
companion object {
// 包裹了所有静态属性和方法
val param1
fun fun1(){
}
}
}
调用
Data.param1
Data.fun1()
2、object天生的单例
object全局声明的对象只有一个,所以他就是天生的单例,
object Data{
param1:1
param2:1
}
这就是一个简单的单例
调用
Data.param1
3、object表达式
object表达式对应的是java的匿名内部类,
1、object 声明不能放在函数中,但是可以放在其他object 声明中或者类声明中
2、object表达式可以赋值给一个变量方便调用
3、匿名内部类只能继承或者实现一个接口,object表达式没有此限制
比如某个控件 的监听事件就是你们内部类就可以用object实现,
当匿名内部类只有一个方法时是可以用lambda表达式替换匿名内部类实现的。
下次更新学习笔记内容“代数数据类型和模式匹配”
喜欢 就关注吧,欢迎投稿!
本网站文章均为原创内容,并可随意转载,但请标明本文链接
如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: https://leetcode.jp/kotlin面向对象(学习笔记二)/