Kotlin 类的继承

Kotlin 类的继承,如果在一个类中想要使用已有类中的所有属性或方法,则可以通过将该类继承已有类来实现。类的继承是面向对象中最显著的一个特性,继承是从已有的类中派生出新的类,新的类能够重写已有类的属性和方法,并可以扩展新的功能。在程序中使用类的继承可以很容易地复用之前的代码,从而大大缩短开发周期,降低开发费用,本章我们将针对类的继承进行详细的讲解。

类的继承

在Kotlin中,类的继承是指在一个现有类的基础上去构建一个新类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法。在程序中如果想声明一个类继承另一个类,则需要使用英文冒号“:”,由于Kotlin中的所有类都默认使用final关键字修饰,不能被继承,因此,当继承某个类时,需要在这个类的前面加上open关键字。接下来我们通过一个案例来学习类的继承,具体代码如下所示。

package com.itheima.chapter04
open class Father() {
    fun sayHello() {
        println("Hello")
    }
}
class Son : Father() {
}
fun main(args: Array<String>) {
   var son =Son()
   son.sayHello()
}

运行结果:

Hello

在上述代码中,使用open关键字修饰Father类,使其他类可以继承Father类。Son类通过“:”继承了Father类,这样Son类便是Father类的子类。从运行结果可知,子类Son中虽然没有sayHello()方法,但却能调用父类的这个方法打印字符串,这就说明,子类在继承父类的时候,会自动继承父类的所有方法。

继承的几种情况

(1)在Kotlin中,一个类只能继承一个父类,不能继承多个父类,即一个类只能有一个父类,例如下面的这种情况,在编译器中会报错的。

open class A{} 
open class B{} 
class C : A(),B(){   //C类不可以同时继承A 类和B 类 
}

(2)多个类可以继承一个父类,例如下面这种情况是可以的。

open class A {} 
class B : A() {} 
class C : A() {}    //类B 和类C 都可以继承类A

(3)在Kotlin中,多层继承也是可以的,即一个类的父类可以再去继承另外的父类,例如C类继承B类,而B类又可以去继承A类,这时,C类也可称作A类的子类,具体示例如下所示。

open class A {} 
open class B : A() {}   // 类B 继承类A,类B 是类A 的子类 
class C : B() {}        // 类C 继承类B,类C 是类B 的子类,同时也是类A 的子类

注意:如果类B需要被类C继承,则类B前边必须添加关键字open。

(4)在Kotlin中,子类和父类是一种相对概念,也就是说一个类是某个父类的同时,也可以是另一个类的子类。例如上面的实例中,B类是A类的子类,同时又是C类的父类。

方法重写

在Kotlin程序中,经常会用到类的继承,子类继承父类时会自动继承父类中定义的方法或属性,但有时在子类中需要对继承的方法或属性进行一些修改,这个过程被称为方法或属性的重写。方法和属性的重写需要注意以下几点。

  • 在子类中重写的方法与在父类中被重写的方法必须具有相同的方法名、参数列表以及返回值类型,并且被重写的方法前边需要使用“override”关键字标识。
  • 在子类中重写的属性与在父类中被重写的属性必须具有相同的名称和类型,并且被重写的属性前边也需要使用“override”关键字标识。
  • 在父类中需要被重写的属性和方法前面必须使用open关键字来修饰。

接下来我们通过一个案例来描述父类中的方法和属性的继承,具体代码如下所示。

package com.itheima.chapter04
open class Father() {
    open var name = " 江小白"
    open var age = 35
    open fun sayHello() {
        println("Hello !我叫$name,我今年$age 岁。")
    }
}
class Son : Father() {
   override var name = " 小小白"
   override var age = 5
   override fun sayHello() {
       println("Hello !我是江小白的儿子,我叫$name,我今年$age 岁。")
   }
}
fun main(args: Array<String>) {
   var father = Father()
   father.sayHello()
   var son = Son()
   son.sayHello()
}

运行结果:

Hello!我叫江小白,我今年35岁。
Hello!我是江小白的儿子,我叫小小白,我今年5岁。

在上述代码中,定义了一个Son类继承Father类,在子类Son中定义了name和age属性对父类中的属性进行重写,同时还定义了一个sayHello()方法对父类中的方法进行重写。在main()函数中,分别创建父类对象和子类对象,并调用各自的sayHello()方法。根据运行结果可知,调用子类对象中的sayHello()方法时,只会调用子类重写的这个方法,并不会调用父类的sayHello()方法,同时name和age的属性值也只调用的子类中重写的属性值。

super关键字

类的继承中,当子类重写父类的方法后,子类对象将无法访问父类被重写的方法,为了解决这个问题,在Kotlin中专门提供了一个super关键字用于访问父类的成员。例如访问父类的成员变量、成员函数等。
使用super关键字调用父类的成员变量和成员方法的语法格式如下:

super.成员变量
super.成员方法([形参1,形参2…])

接下来我们在上面代码的基础上进行改写,通过super关键字访问父类成员变量和成员方法,具体如下所示。

package com.itheima.chapter04
open class Father() {
    open var name = " 江小白"
    open var age = 35
    open fun sayHello() {
        println("Hello !我叫${name},我今年${age} 岁。")
    }
}
class Son : Father() {
   override var name = " 小小白"
   override var age = 5
   override fun sayHello() {
       super.sayHello()
    println("Hello!我是${super.name} 的儿子,我叫${name},我今年${age} 岁。")
   }
}
fun main(args: Array<String>) {
   var son = Son()
   son.sayHello()
}

运行结果:

Hello!我叫小小白,我今年5岁。
Hello!我是江小白的儿子,我叫小小白,我今年5岁。

上述代码中,第13和14行分别是通过super关键字来调用父类Father中的成员变量name和成员方法sayHello()。

Any类与Object类

Kotlin中所有类都继承Any类,它是所有类的父类,如果一个类在声明时没有指定父类,则默认父类为Any类,在程序运行时,Any类会自动映射为Java中的java.lang.Object类。接下来,我们通过一个案例来演示在程序运行时Any类的变化,具体代码如下:

fun main(args: Array<String>) {
    println(Any().javaClass)
}

运行结果:

class java.lang.Object

在上述代码中,javaClass属性代表运行时对象的类型,根据程序的运行结果可知,Any类的对象在程序运行时的类型为“java.lang.Object”,即Any类会自动映射为Java中的java.lang.Object类。

在Kotlin中,所有类型都是引用类型,这些引用类型统一继承父类Any,Any类中默认提供了3个方法,分别是equals()hashCode()toString(),这3个方法的作用如表所示。

方法名 方法作用
equals() 检测两个对象是否相等
hashCode() 返回一个对象的哈希值
toString() 返回一个对象的字符串形式

在Java中,Object类是所有引用类型的父类,但不包括基本类型Int、Long、Double等,Object类中默认提供了11个方法,分别是equals()、hashCode()、toString()、getClass()、clone()、finalize()、notify()、notifyAll()、wait()、wait(long)、wait(long,int),这11个方法的作用如表所示。
Kotlin 类的继承

酷客教程相关文章:

赞(0)

评论 抢沙发

评论前必须登录!