【3】Kotlin基础——类的继承与构造函数

提示:此文章仅作为本人记录日常学习使用,若有存在错误或者不严谨得地方,欢迎各位在评论中指出。

一、类的继承

Kotlin语言和Java语言都是单继承,它们的区别在于Kotlin中用冒号":"代替了Java中的"extends"关键字

1.1 类与对象

在开始类的继承之前,我们先来了解一下如何用Kotlin语言声明一个类并对其进行实例化。

class Person {
	//字段
    var name = ""
    var age = 0
    //方法
    fun eat() {
        println(name + "is eating. He is " + age + "years old.")
    }
}

通过以上代码我们就成功定义了一个Person类,并使用var关键字(为了后续可以对其重新进行赋值)声明了name和age这两个字段。接下来,我们在Person类中声明了一个eat()方法,并让它打印一句话。

Person类已经创建好了,现在我们来了解一下如何对这个Person类进行实例化(创建对象):

val p = Person()

我们使用val关键字定义了一个不可变的变量p,并且通过Person()构造函数创建了一个Person对象。

1.2 类的继承

在类的继承上,Kotlin和Java还是存在些许不同的。在Kotlin语言中,一个类若想要被继承,需要在这个类前面加上open关键字

//通过open关键字来告诉Kotlin编译器 Person这个类是专门为继承而设计的
open class Person {
    · · ·
}

为了更好地理解类的继承,我们来看一段示例代码。在这段代码中我们声明了一个Student类和一个Person类,并让Student类继承自Person类:

//Person类(open关键字让该类允许被继承)
open class Person {
}

//Student类继承自Person类
       子类  继承  父类
class Student : Person() {
    var sno = ""
    var grade = 0
}

二、构造函数

Kotlin语言中将构造函数分成了两种:主构造函数次构造函数。我们使用最多的就是主构造函数,而次构造函数接触的机会很少很少。

1.1 主构造函数

在Kotlin语言中每个类默认都会有一个不带参数的主构造函数,我们也可以显式的给它指明参数。主构造函数的特点就是没有函数体,直接定义在类名的后面:

        子类             主 构 造 函 数          继承   父类
class Student(val sno: String, val grade: Int) : Person() {
}

在上述代码中我们将“学号sno”和“年级grade”都放入到主构造函数中。在对Student类进行实例化(创建对象)的时候,必须传入构造函数中要求的所有参数

val student = Student("s10001", 6)

通过这种方式我们就创建了一个Student对象,他的学号是s10001,他的年级是6。

1.1.1 主构造函数——init结构体

前面我们说过"主构造函数直接定义在类名的后面,是没有函数体的"。那么我们该如何在主构造函数中添加逻辑呢?Kotlin语言提供了一个叫init{ }的结构体,所有主构造函数中的逻辑都可以写在init{ }结构体中

class Student(val sno: String, val grade: Int): Person() {
    init {
        println("sno is:" + sno + "grade is:" + grade)
    }
}

需要注意的是,在Kotlin语言中要求子类的构造函数必须调用父类中的构造函数。所以在前面Student类继承Person父类时,Person类后面的那一对括号其实代表Student子类的主构造函数在初始化的时候会调用Person父类的无参构造函数

                                                 父类的无参构造函数
class Student(val sno: String, val grade: Int) : Person() {
}

前面我们定义的Person类中有name和age两个字段。

class Person {
    var name = ""
    var age = 0
    fun eat() {
        println(name + "is eating. He is " + age + "years old.")
    }
}

如果我们尝试将Person类改造一下,把姓名和年龄都放到主构造函数中。

class Person(val name: String, val age: Int) {  
    fun eat() {  
        println(name + " is eating. He is " + age + " years old.")  
    }  
}

此时,Student类中以下代码的Person()是会报错的:

                                                  报错
class Student(val sno: String, val grade: Int): Person() {
    init {
        println("sno is:" + sno + "grade is:" + grade)
    }
}

报错的原因是 Person()表示要调用Person类的无参构造函数,但是Person类现在已经没有无参构造函数了,所以就会报错。若想解决这个问题需要给Person类的构造函数传入name和age这两个字段。我们可以在Student类的主构造函数中加入name和age这两个参数,再将这两个参数传给Person类的构造函数

//Person()会报错
class Student(val sno: String, val grade: Int): Person() {
    · · ·
}
     |
     | fix
     |
     V
//Person()不会报错
class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name,age) {
    · · ·
} 

这里需要注意,我们在Student类的主构造函数中增加name和age这两个字段时,就不能再将它们声明成val了。因为在主构造函数中声明成val或者var的参数会自动成为该类的字段,这样就会导致和父类中同名的name和age字段造成冲突。因此,这里的name和age参数前面不用添加任何关键字,让他的作用域只限定在主构造函数当中即可。

val student = Student("s10001", 6 , "Mike", 18)

1.2 次构造函数

次构造函数使用的场景很少,任何一个类只能有一个主构造函数,但是却可以有多个次构造函数。Kotlin语言规定,当一个类中既有主构造函数又有次构造函数时,所有的次构造函数都必须(直接或者间接)的调用主构造函数。次构造函数是通过constructor关键字来定义的:

class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name,age) {
    //次构造函数①:接收2个参数,并通过this关键字调用4个参数的构造函数(主构造函数)
    constructor(name: String, age: Int) : this("", 0, name, age) {
    }
    //次构造函数②:不接收任何参数,并通过this关键字调用2个参数的次构造函数①
    //由于次构造函数①调用了主构造函数,而次构造函数②又调用了次构造函数①
    //相当于次构造函数②间接调用了主构造函数,是符合Kotlin语言要求的
    constructor() : this("", 0) {
    }
}

接下来我们就可以通过三种方式来对Student类进行实例化:①通过不带参数的构造函数②通过带两个参数的构造函数③通过带四个参数的构造函数。

//对应次构造函数②   constructor() : this("", 0)
val student1 = Student()
//对应次构造函数①   constructor(name: String, age: Int) : this("", 0, name, age)
val student2 = Student("Mike", 18)
//对应主构造函数
val student3 = Student("s10001", 6, "Mike", 18)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值