Kotlin第五讲——类定义与继承

avatar
Android @奇舞团Android团队
原文链接: mp.weixin.qq.com

内容简介:面向对象开发,最重要的就是定义一个类。Java 的世界中存在很多类(内部类丶匿名内部类丶静态类丶枚举类等),Kotlin也存在这些类,只是在定义的有些许不同,并增加了一些特有的类(密封类 丶 data类等)。接下来让我们来看看这些类如何定义,以及其功能。

定义一个类

Java 类只能定义在一个与类同名的 .java 文件中(先不考虑内部类)。在 Kotlin 中你可以不这样做了。你可以在同一个 .kt 文件里定义多个类。

    package com.qihoo.kot

    class DemoClass

Kotlin 定义一个类就是这么简单,但是这个类没有任何意义。需要注意的是 Ktolin 默认定义的类都是 public final 类型的( Kotlin 也不使用这 2 个关键词了)。

构造函数

我们都知道 Java 创建一个对象都需要调用其类的构造函数。Kotlin 也具有这个特点,只是构造函数的定义上存在一些区别。

主构造函数

Java 所有的类都会有一个默认隐藏的无参构造函数。Kotlin 与之对应的函数,称之为 主构造函数  ,Kotlin 的主构造函数默认也是隐藏的,但是主构造函数可以定义参数的。

    /**

    * 创建一个 Empty 类, 并且主构造函数有2个参数

    */

    class Empty(name: String, age: Int)

    fun main() {

    /**

    * 调用构造函数,创建一个实例

    */

    val empty = Empty("阿文", 18)

    }

次构造函数

既然存在主构造函数,那么就会存在次构造函数。Kotlin 的次级构造函数,类似于 Java 的构造函数重载,不同的是 Kotlin 的次级构造函数,一定要与主构造函数关联。定义一个次级构造函数使用  constructor  定义方法即可。

    /**

    * 创建一个 Empty 类, 并且主构造函数有2个参数

    */

    class Empty(name: String, age: Int) {

    /**

    * 定义次构造函数

    * 由于我定义了主构造函数,所以必须要 使用 : this(XXX) 的形式调用主构造函数

    */

    constructor(name: String, age: Int, sex: String) : this(name, age) {

    }

    }

构造函数 init 方法

曾几何时,Java 中我们经常自定义 View,需要重写 N 个构造函数,然后每个函数都要调用 init 方法。做一些初始化画笔等功能。在 Kotlin 中 init 方法具有类似的功能,在调用构造函数之后会调用(有点类似构造代码块)。

例如:

    class Empty(name: String, age: Int) {

    init {

    println("对象创建:$name $age ")

    }

    /**

    * 也可以定义多个 init 方法,执行顺序从上到下

    */

    init {

    println("对象创建22:$name $age")

    }

    }

构造函数修饰符

还记得 Java 中单例吗?第一件事就是私有化的隐藏无参构造函数。 Kotlin 对应的就是私有化主构造函数了。

    /**

    * 构造方法权限符修饰

    */

    class DemoClass private constructor(){

    /**

    * 也可以 私有化次构造函数

    */

    private constructor(name: String, age: Int) : this() {

    }

    }

补充一个小点,不然后面的继承有点知识盲点。如果定义了次级构造函数且主构造函数没有明确指定(默认使用隐藏的主构造函数),那么次级构造函数无需做主构造函数的关联。

    /**

    * Empty 类的主构造函数没有被重新定义

    */

    open class Empty {

    /**

    * 可以发现 次构造函数可以,省略不写 :this()

    */

    constructor(name: String)

    }

类函数

既然讲了如何通过定义构造函数定义了类,那么定义类的属性和函数是必不可少的了。其实定义的次构造函数也是函数(Kotlin 中的函数,会分一个大章节来详细讲解)。定义函数需要使用 fun  修饰符来修饰,默认定义的函数都是 public final.

    open class Empty {

    /**

    * 定义 call 函数,并定义行参 type

    */

    fun call(type: Int) {

    }

    }

类属性

还记得在 Java中构造函数中,为类成员变量赋值的写法吗?

    public class Empty {

    private final int name;

    private final int age;

    public Empty(String name, int age) {

    this.name = age;

    this.age = age;

    }

    }

来看看 Kotlin 的简单写法!我们只需要在主构造函数中,使用 val  或 var  修饰符修饰变量,对应的变量就会变成类的成员变量了(此功能只能使用在主构造函数中)。

    open class Empty(val name: String, val age: Int)

当然我们也可以定义其他的成员变量。

    open class Empty(val name: String, val age: Int){

    val sex: String = "男"

    }

继承

前面说过 Kotlin 的默认定义的 class 是默认 final 类型的,也就是不可以继承。如果要继承必须使用 open 符修饰。Kotlin 中的继承不再像 Java 使用 extends 而是替换成了  :

例如:

    /**

    * open 修饰

    */

    open class A(val name: String)

    /**

    * B 继承 A 类,中间用 :

    */

    class B(name: String) : A(name)

重写属性和方法

Java 的世界中,只存在重写方法。但是 Kotlin 是可以重写属性&重写方法,只需要用 override 修饰即可。

    /**

    * open修饰

    */

    open class A {

    // value 记得 open

    open val value = 0

    }

    /**

    * B继承A类

    */

    class B : A() {

    // 覆盖A的 value 值,要用 override

    override val value = 1

    }

重写方法:

    /**

    * B 继承 A 类

    */

    class B : A() {

    // 覆盖A的value值

    override val value = 1

    override fun test() {

    super.test()

    // 若要获取父类的属性 通过 super关键词

    val superValue = super.value

    println("父类的$superValue")

    }

    }

推荐阅读

--END--

识别二维码,关注我们