Kotlin——继承

开发 后端
在Kotlin中,实现继承由以下规则控制:如果类从其直接超类继承同一成员的多个实现,则它必须覆盖该成员并提供自己的实现(可能使用其中一个继承)。 要表示从其继承的实现的超类型,可在尖括号中使用超类型名称超级限定。

Kotlin——继承

Kotlin中所有的类都有一个公有的超类:Any,这是所有没有声明超类的类的默认父类。

  1. class Example //隐式继承自Any 

Any!=Java.lang.Object。尤其,除了equals()、hashCode()和toString()三个方法外,没有任何成员。

为了显式地声明超类,语法如下:

  1. open class Base(p:Int
  2.  
  3. class Derived(p:Int):Base(p) 

 

如果类具有主构造器,则可以使用主构造器的参数(并且必须)初始化父类。

如果类没有主构造器,那么每个辅助构造器初始化时需要使用super关键字,或者将其委托给其他构造器。需要注意的是,在这种情况下,不同的辅助构造器可以调用基类的不同构造器。

  1. class MyView:View
  2.  
  3. constructor(ctx:Context):super(ctx) 
  4.  
  5. constructor(ctx:Context,attrs:AttributeSet):super(ctx,attrs) 
  6.  

 

open注解和Java的final相反:它允许其他类继承自该类。默认的,Kotlin中所有的类是final的,也就是说不能继承的。

覆写方法

Kotlin总是做一些明确的事情,不像Java,Kotlin要求复写方法时需要显式的注解和重写:

  1. open class Base { 
  2.     open fun v() { 
  3.         println("Base.v()"
  4.     } 
  5.  
  6.     fun nv() { 
  7.         println("Base.nv"
  8.     } 
  9.  
  10.  
  11. class Derived() : Base() { 
  12.  
  13.     override fun v() { 
  14.         println("Derived.v()"
  15.     } 
  16.  

 

复写Derived的v()时,ovverride注解是必须的,否则编译器会报错。如果没有open注解,比如Base的nv(),那么在子类中是不能覆写该方法的。在一个final类中(没有open注解声明),open成员是禁止的。也就是说final类的每个成员也都是final的。

一个标记为override的成员自身就是open的,子类仍然可以覆写它。如果你想禁止覆写,那么使用final

  1. open class AnotherDerived() : Base() { 
  2.     final override fun v() { 
  3.         println("AnotherDerived.v"
  4.     } 

 

***,main()验证多态性:

  1. fun main(args: Array<String>) { 
  2.  
  3.     var base1: Base = Base() 
  4.     var base2: Base = Derived() 
  5.     var base3: Base = AnotherDerived() 
  6.  
  7.     base1.v() 
  8.     base2.v() 
  9.     base3.v() 
  10.  

 

覆写属性

覆写属性和覆写方法基本类似;如果子类要重新声明父类中已经声明过的属性,那么需要使用override,并且类型要兼容。每个声明的属性可以被具有初始化器的属性或具有getter方法的属性覆盖。

  1. open class Foo { 
  2.     open val x: Int 
  3.         get() { 
  4.             println("Foo"
  5.             return 3 
  6.         } 
  7.  
  8. class Bar1 : Foo() { 
  9.     override val x: Int = 2 

 

可以使用var属性覆盖val属性,反之不可以。因为val属性基本上声明一个getter方法,并将其替换为var,另外在派生类中声明一个setter方法。

可以在主构造器使用override覆盖属性

  1. interface Aoo { 
  2.     val countInt 
  3.  
  4. class Aoo1(override val countInt) : Aoo 
  5.  
  6. class Aoo2 : Aoo { 
  7.     override var countInt = 0 

 

覆写准则

在Kotlin中,实现继承由以下规则控制:如果类从其直接超类继承同一成员的多个实现,则它必须覆盖该成员并提供自己的实现(可能使用其中一个继承)。 要表示从其继承的实现的超类型,可在尖括号中使用超类型名称超级限定,例如,super。

  1. open class A { 
  2.     open fun f() { 
  3.         println("A"
  4.     } 
  5.  
  6.     fun a() { 
  7.         println("a"
  8.     } 
  9.  
  10.  
  11. //接口的方法默认open 
  12. interface B { 
  13.     fun f() { 
  14.         println("B"
  15.     } 
  16.  
  17.     fun b() { 
  18.         println("b"
  19.     } 
  20.  
  21.  
  22. class C() : A(), B { 
  23.     override fun f() { 
  24.         super<A>.f() 
  25.         super<B>.f() 
  26.         println("C"
  27.     } 

 

上面的代码继承自A和B是没有问题的,a()和b()因为C知道继承自哪一个类。但是对于f(),我们有两个继承,所以我们需要覆写f(),并且需要提供我们的实现来消除歧义。

总结

Kotlin中的类默认是final的,如果需要子类继承,需要使用open修饰;

Kotlin中的方法默认是不允许复写的,只有用open修饰时,子类才可以进行覆写,并且需要使用override进行显示标注

属性也支持覆写 

责任编辑:庞桂玉 来源: Android开发中文站
相关推荐

2022-02-28 10:38:13

Kotlin插件Android

2017-05-19 18:01:04

GoogleKotlin数据

2009-07-14 17:36:28

Jython的继承

2018-06-05 10:30:28

KotlinJava语言

2011-08-24 13:56:27

JavaScript

2018-01-03 11:51:06

KotlinTipsJava

2012-02-14 09:45:02

JavaScript

2012-02-02 16:13:29

HibernateJava

2011-07-07 13:39:14

Cocoa 框架

2011-08-31 14:48:33

JavaScript

2024-01-08 09:00:00

开发DSLKotlin

2023-10-24 19:37:34

协程Java

2009-07-02 09:40:14

Hibernate的继

2021-09-16 16:08:43

KotlinAndroidAOSP

2020-09-30 06:47:22

Kotlin机制

2017-07-05 17:50:52

KotlinJava程序员

2018-05-15 16:12:59

Kotlin扩展XxxUtils

2024-01-31 14:53:09

Kotlin云端缓存

2011-03-10 14:19:56

JavaScript

2021-12-04 11:17:32

Javascript继承编程
点赞
收藏

51CTO技术栈公众号