Kotlin-Anko学习(4)Kotlin语法-类、继承、抽象类

本系列文章来学习 Kotlin 和 Anko 插件 通过 Kotlin 开发一个 Android 项目。

Kotlin-Anko学习(1) Kotlin、Anko 介绍

Kotlin-Anko学习(2) Kotlin 语法基础-基本类型

Kotlin-Anko学习(3) Kotlin 语法基础-关键字 package、Import、if、when、for、while、return、break、continue

Kotlin-Anko学习(4) Kotlin语法-类、继承、抽象类

Kotlin 类

与Java相同,类由 class 关键字声明。

类声明的组成

类名 TestKot:

类头 在类名后声明属性、指定其类型参数、主构造函数等。 如

类体 TestKot: 大括号中为类体部分,如果类没有类头,类体可以简写成。类体中可以包含:

构造函数和初始化块

函数

属性

嵌套类和内部类

对象声明

构造函数、属性初始化、初始化块

Kotlin 中一个类可以包含一个主构造函数和一个或多个次构造函数,用关键字constructor修饰

Kotlin 中属性初始化可以在类头中,也可以在类体中写,并且可以获得主构造函数的参数值

Kotlin 中由于主构造函数在类头中,不能写初始化代码,所以Kotlin 通过一个关键字 init 来包含初始化代码块

主构造函数(primary constructor ):

如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。如下:

次构造函数(secondary constructor ):

如果类有一个主构造函数,每个次构造函数需要委托给主构造函数, 可以直接委托或者通过别的次构造函数间接委托。委托到同一个类的另一个构造函数用 this 关键字。

运行结果:

从以上代码可以看出,属性初始化和init初始化代码块是按顺序执行的,次构造函数式在属性初始化和init执行完才开始的,所以可以把属性初始化和init初始化代码块当做主构造函数体来理解。这样构造函数部分就讲完了。

类的实例化

Kotlin 中类的实例化就像普通函数一样直接调用,如上面的main函数中的示例,不需要new与java不同,也没有new关键字。

Kotlin 继承

与java不同,kotlin中类的继承在类头后加冒号: “Current类:Base类”

Any 超类

Kotlin 中所有类都有一个共同的超类 Any,不同于java的Object类,只有三个方法代码如下:

open关键字

open 标注与 Java 中 final 相反,它允许其他类从这个类继承。默认情况下,在 Kotlin 中所有的类都是 final,抽象类不需要用open修饰。

上面代码可以看出超类有构造函数的话,其基类可以(并且必须) 用(基类型的)主构造函数参数就地初始化。

super 关键字

super与java类似,用于超类属性、方法的实现,这里我们看派生类如何初始化超类的构造函数

以上代码可以看出,超类没有主构造函数,基类可以通过主构造函数初始化超类的任意一个次构造函数,在此基础上,基类的次构造函数不能通过super来初始化超类的其他次构造函数,如示例1,2;基类也可以不声明主构造函数,通过次构造函数super来初始化对应的次构造函数,如示例3。

override 关键字

Kotlin 中 override 只能修饰父类显式标注可覆盖的成员(开放open),父类中没有显式标注的成员在其子类中不允许定义相同签名的函数。

覆盖方法

示例1:说明父类的显式标注方法,在子类中可以通过override修饰的相同方法覆盖,对于没有开放的函数, 不论加不加 override,都不允许定义与父类相同签名的方法。

示例2:说明在一个 final 类中(没有用 open 标注的类),open修饰的方法没有用

示例3:说明子类重写的方法如果想在,子类的子类中不被继续重写,可以在override前用final 进行修饰。

覆盖属性

输出结果:

重写属性的规则也是通过override进行修饰,并且派生类的重写的属性必须兼容超类的属性,示例1可以看出

声明的属性由具有初始化器的属性或者具有 getter 方法的属性覆盖 ,示例2可以看出用一个 var 属性覆盖一个 val 属性是可以的,本质上var的get方法覆盖了val的get方法,并且在派生类额外生成一个set方法。

调用超类的实现

调用超类中的方法与java相同,通过super关键字修饰,属性属kotlin独有的。

输出结果:

以上就是派生类中调用超类具体的实现,跟java相似。

覆盖规则

既有继承又有接口的实现

Kotlin 中一个类从它的直接超类继承相同成员的多个实现, 它必须覆盖这个成员并提供其自己的实现。 为了表示采用从哪个超类型继承的实现,我们使用由尖括号中超类型名限定的 super,如 super

输出结果:

首先在派生类既有继承又有接口,并且超类、接口中存在相同的方法,派生类必须重写该方法,并且通过

surper.f() 尖括号中表明实现哪个父类的方法,并且这里说明一下kotlin中接口中的方法默认是open的。

内部类中访问外部类超类的实现

输出结果:

内部类需要实现外部类的属性和方法,我们super@Outer().f()、super@Outer.x来实现。

抽象类

kotlin 中抽象类和java相同,通过 abstract 关键字来修饰,抽象类中可以包含抽象的方法或属性。

输出结果:

上面的代码可以看出,非抽象的超类可以派生出抽象类,并且开放的方法可以被重写成抽象方法,抽象方法是不允许有方法体的,abstract 修饰的属性或方法默认是open的。这里与接口不同,接口中的方法默认抽象的也是默认开放的,抽象类中的方法只有抽象的方法才是默认open的。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180111A0QGE200?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券