类与对象
Kotlin中也是使用class关键字来声明一个类的,这一点与Java一致。
class Person{
var name = ""
var age = 0
fun eat(){
println(name + " is eating. He is " + age + " years old. ")
}
}
Kotlin对这个类进行实例化,这个跟Java的基本类似,但是去掉了new的关键字。当你调用了某个类的构造函数时,你的意图只可能是对这个类进行实例化,没必要使用new关键字,就去掉了。
val p = Person()
fun main(){
val p = Person()
p.name = "Jack"
p.age = 19
p.eat()
}
继承与构造函数
继承
1、使Person类可以被继承,除了抽象类,非抽象类默认是不可被继承的。加上open关键字这个类就可以被继承了。
open class Person{
var name = ""
var age = 0
fun eat(){
println(name + " is eating. He is " + age + " years old. ")
}
}
2、要让Student类继承Person类。在Java中的继承关键字是extends,而在Kotlin中变成了一个冒号,写法如下:
class Student : Person(){
var name = "Jack"
var age = 18
}
主构造函数和次构造函数
主构造函数
主构造函数是常用的构造函数,每个类都会默认有一个不带参数的主构造函数,当然也可以给它显式地给它指明参数。主构造函数的特点是没有函数体,直接定义在类名后面即可。
class Student(val sno: String,val grade: Int) : Person(){
}
这里我们将学号和年级这两个字段都放到了主构造函数中,这就表明在对Student进行实例化的时候,必须要传入构造函数中要求的所有参数。
val student = Student("a123" , 5)
需要在主构造函数里编写一些逻辑,Kotlin给我们提供了一个init结构体,所有主构造函数中的逻辑都可以写在里面。
无参数主构造函数:
class Student(val sno: String,val grade: Int) : Person(){
init{
println("sno is " + sno)
println(" grade is " + grade)
}
}
有参主构造函数:
open class Person(val name: String, val age: Int){
...
}
class Student(val sno: String, val grade: Int,name: String,age: Int) :
Person(name,age){
}
val student = Student("a123",5,"Jack",19)
次构造函数
任何一个类只能有一个主构造函数,但可以有多个次构造函数。次构造函数可以用于实例化一个类,这一点和主构造函数没什么不同,只不过它是有函数体的。
class Student(val sno: String, val grade: Int,name: String,age: Int) :
Person(name,age){
constructor(name: String,age: Int) : this("",0,name,age){
}
constructor() : this("",0){
}
}
次构造函数是通过constructor关键字来定义的,这里我们定义了两个次构造函数:第一个次构造函数接收name和age参数,然后它有通过this关键字调用了主构造函数,并将sno和grade这两个参数赋值成初始值;第二个次构造函数不接收任何参数,它通过this关键字调用了我们刚才定义的第一个次构造函数,并将name和age参数也赋值成初始值,由于第二个次构造函数间接调用了主构造函数,因此这是合法的。
val student1 = Student()
val student2 = Student("Jack",19)
val student3 = Student("a123",5,"Jack",19)
!!!一种非常特殊的情况
类中只有次构造函数,没有主构造函数。当一个类没有显式地定义主构造函数且定义了次构造函数时,它就是没有主构造函数的。
class Student : Person{
constructor(name: String,age: Int) : super(name,age){
}
}
由于没有主构造函数,次构造函数只能直接调用父类的构造函数,上述代码也是将this换成了super关键字。还有Person不用加括号,有主构造函数就加没有就不加。
接口
!!!接口中的函数不要求有函数体
interface Study{
fun readBooks()
fun doHomework()
}
class Student(name: String,age: Int): Person(name,age),Study{
override fun readBooks(){
println(name + "is reading.")
}
override fun doHomework(){
println(name + "is doing homework.")
}
}
//多态
fun main(){
val student = Student("Jack",19)
doStudy(student)
}
fun doStudy(study: Study){
study.readBooks()
study.doHomework()
}
接口中函数的默认实现,就是不管在实现类中重写了该函数,还是没有实现该函数,但还是会执行在接口中默认实现的函数体。
interface Study{
fun readBooks(){
}
fun doHomework(){
println("do homework default implementation.")
}
}
在实现接口的类中可以不强制实现默认实现的函数,但是函数没有默认实现的话是需要强制实现的。