一.继承
①kotlin中继承的最基本操作:
将父类open然后再继承
因为在kotlin中任何一个非抽象类默认都是不可以被继承的,这一点在Java中其实也有类似的思想,在《Effective Java》这本书中明确提到,如果一个类不是专门为继承而设计的,那么就应该主动将它加上final声明,禁止它可以被继承
open class Father{
}
class Student(): Father(){
}
②主构造函数
主构造函数的特点是没有函数体,直接定义在类名的后面即可
如果想在主构造函数中编写一些逻辑,那么可以在init结构体中书写(多数情况下是不用init结构体的)
class Student(val son: String,val grade: Int): Father(){
init{
println(son)
println(grade)
}
}
由于kotlin中有一个规定:子类中的构造函数必须调用父类中的构造函数,因此就有了冒号后面的Father(),空括号表示Father的无参构造函数,即使没有参数,这对括号也不能省略
所以
open class Father(val name: String,val age: Int){
}
class Student(val son: String,val grade: Int): Father(){
}
就会报错,因为Father里面没有无参数的构造函数了,想要解决这个问题,就可以在Student上加
open class Father(val name: String,val age: Int){
}
class Student(val son: String,val grade: Int,name: String,age: Int): Father(name,age){
}
注意:这里加name和age时,不能再把它们声明成val或者var,因为在主构造函数中声明val或者var的参数将自动成为该类的字段,这就会导致和父类中同名的name和age字段造成冲突,因此这里的name和age不需要加任何关键字,让它的作用域仅仅限定在主构造函数中即可(因为主构造函数中默认调用了父类的构造函数,所以在这里的name和age可以传到父类的构造函数,也就是在其作用域内)
③次构造函数
kotlin中规定,所有的次构造函数必须直接或者间接地调用主构造函数
class Student(val son: String,val grade: Int,name: String,age: Int): Father(name,age){
//这是直接调用了主构造函数
constructor(name: String,age: Int): this("",0,name,age)//这里也和继承的时候类似,name和age不用加var/val
//这是间接调用了主构造函数
constructor():this("",0)
}
还有一种十分特殊十分少见地情况,当一个类没有显式地定义主构造函数且定义了次构造函数时,它就是没有主构造函数的
open class Father(val name: String,val age: Int){
constructor()
}
class Student: Father{
constructor(name: String,age: Int): super(name,age)
}
因为Student没有主构造函数,所以后面没有(),没有主构造函数,就更不用提“在主构造函数里面调用父类的构造函数了,因此Father后面也不能加括号,因为在Student的主构造函数里面根本没有调用Father的构造函数。
注意:因为没有主构造函数,因此次构造函数只能直接调用父类的构造函数了,因此也就有了super
二.接口
总体来说java中的接口和kotlin中的接口知识点基本是一样的
①基本使用
Java是单继承结构的语言,任何一个类最多只能继承一个父类,但是却可以实现任意多个接口,kotlin也是如此
注意接口中的函数不要求有函数体(子类继承接口时要用override)
interface Study{
fun readBook()
fun doHomeWork()
}
class Student:Study{
override fun doHomeWork() {
}
override fun readBook() {
TODO("Not yet implemented")
}
}
②函数的默认实现
kotlin和JDK1.8之后一样,都允许对接口中定义的函数进行默认实现
比如
interface Study{
fun readBook()
fun doHomeWork(){
println("doHomeWork")
}
}
class Student:Study{
override fun readBook() {
TODO("Not yet implemented")
}
}
③可见性修饰符
Java和kotlin的可见性修饰符之间有区别,具体为
三.数据类
数据类通常用于将服务器端或数据库中的数据映射到内存中,在Java中的数据类看上去很繁琐,但是kotlin就完全相反。
data class Cellphone(val brand: String,val price: Double)
fun main() {
val Cellphone1 = Cellphone("华为",10000.0)
val Cellphone2 = Cellphone("华为",10000.0)
println(Cellphone1)
println("Cellphone1 equals Cellphone2" + (Cellphone1 == Cellphone2))
}
/*
Cellphone(brand=华为, price=10000.0)
Cellphone1 equals Cellphone2true
*/
kotlin会根据主构造函数中的参数帮你将equals()、hashCode()、toString()等固定且无实际逻辑意义的方法自动生成,从而大大减少了开发的工作量
四.单例类
Java中的单例类就不再多说,kotlin中实现单例类依然很方便,只需要把class 关键字改为 object即可
object Singleton{
fun SingletonTest(){
println("单例类的函数")
}
}
fun main() {
Singleton.SingletonTest()
}
调用的时候也类似于Java中的静态方法的调用方式,虽然看上去像,但实际上kotlin在背后自动帮我们创建了一个Singleton类的实例,并且保证全局只会存在一个Singleton实例