个性化阅读
专注于IT技术分析

Kotlin继承

点击下载

本文概述

继承是面向对象编程语言的重要功能。继承允许将现有类(或基类或父类)的功能继承到新类(或派生类或子类)。

主类称为超类(或父类), 继承超类的类称为子类(或子类)。子类包含超类及其自身的功能。

当两个或多个类具有相同的属性时, 可以使用继承的概念。它允许代码可重用。派生类仅具有一个基类, 但可以具有多个接口, 而基类可以具有一个或多个派生类。

在Kotlin中, 派生类使用类标题中的:运算符(在派生类名称或构造函数之后)继承基类。

open class Base(p: Int){

}
class Derived(p: Int) : Base(p){

}

假设我们有两个不同的类“ Programmer”和“ Salesman”, 它们具有共同的属性“ name”, “ age”和“ salary”, 以及它们各自独立的功能doProgram()和fieldWork()。继承功能使我们可以继承(Employee)包含通用功能。

open class Employee(name: String, age: Int, salary: Float) {
    // code of employee
}

class Programmer(name: String, age: Int, salary: Float): Employee(name, age, salary) {
    // code of programmer
}

class Salesman(name: String, age: Int, salary: Float): Employee(name, age, salary) {
    // code of salesman
}

所有Kotlin类都有一个通用的超类“ Any”。它是没有明确指定超类的类的默认超类。

例如, 类Example从Any隐式继承。

class Example

Kotlin开放式关键字

由于默认情况下Kotlin类是final类, 因此不能简单地继承它们。我们在类之前使用open关键字来继承类并将其设置为非最终类,

例如:

open class Example{
// I can now be extended!
}

Kotlin从类继承字段

当我们继承一个类以派生类时, 所有字段和功能都会被继承。我们可以在派生类中使用这些字段和功能。

例如:

open class Base{
val x = 10
}
class Derived: Base() {
    fun foo() {
println("x is equal to " + x)
    }
}
fun main(args: Array<String>) {
val derived = Derived()
    derived.foo() 
}

输出:

x is equal to 10

Kotlin从类继承方法

open class Bird {
    fun fly() {
println("flying...")
    }
}
class Duck: Bird() {
    fun swim() {
println("swimming...")
    }
}
fun main(args: Array<String>) {
val duck = Duck()
    duck.fly() 
duck.swim()
}

输出:

flying...
swimming...

Kotlin继承示例

在这里, 我们声明一个类Employee为超类, 而Programmer和Salesman是其子类。子类继承属性名称, 年龄和薪水, 并且子类包含其自己的功能, 例如doProgram()和fieldWork()。

open class Employee(name: String, age: Int, salary: Float) {
init {
println("Name is $name.")
println("Age is $age")
println("Salary is $salary")
    }
}
class Programmer(name: String, age: Int, salary: Float):Employee(name, age, salary){
    fun doProgram() {
println("programming is my passion.")
    }
}
class Salesman(name: String, age: Int, salary: Float):Employee(name, age, salary){
    fun fieldWork() {
println("travelling is my hobby.")
    }
}
fun main(args: Array<String>){
val obj1 = Programmer("Ashu", 25, 40000f)
    obj1.doProgram()
val obj2 = Salesman("Ajay", 24, 30000f)
    obj2.fieldWork()
}

输出:

Name is Ashu.
Age is 25
Salary is 40000.0
programming is my passion.
Name is Ajay.
Age is 24
Salary is 30000.0
travelling is my hobby.

Kotlin继承和主要构造函数

如果在这种情况下, 基类和派生类都具有主构造函数, 则在基类的主构造函数中初始化参数。在上面的继承示例中, 所有类都包含三个参数“ name”, “ age”和“ salary”, 并且所有这些参数都在基类的主构造函数中初始化。

当基类和派生类在其主构造函数中都包含不同数量的参数时, 则从派生类对象初始化基类参数。

例如:

open class Employee(name: String, salary: Float) {
init {
println("Name is $name.")
println("Salary is $salary")
    }
}
class Programmer(name: String, dept: String, salary: Float):Employee(name, salary){
init {
println("Name $name of department $dept with salary $salary.")
    }
    fun doProgram() {
println("Programming is my passion.")

    }
}
class Salesman(name: String, dept: String, salary: Float):Employee(name, salary){
init {
println("Name $name of department $dept with salary $salary.")
    }
    fun fieldWork() {
println("Travelling is my hobby.")

    }
}
fun main(args: Array<String>){
val obj1 = Programmer("Ashu", "Development", 40000f)
    obj1.doProgram()
println()
val obj2 = Salesman("Ajay", "Marketing", 30000f)
    obj2.fieldWork()
}

输出:

Name is Ashu.
Salary is 40000.0
Name Ashu of department Development with salary 40000.0.
Programming is my passion.

Name is Ajay.
Salary is 30000.0
Name Ajay of department Marketing with salary 30000.0.
Travelling is my hobby.

创建派生类的对象时, 它将首先调用其超类, 并执行基类的init块, 然后执行其自身的块。

Kotlin继承和辅助构造函数

如果派生类不包含任何主构造函数, 则需要使用super关键字从派生类调用基类的辅助构造函数。

例如,

open class Patent {

    constructor(name: String, id: Int) {
println("execute super constructor $name: $id")
    }
}

class Child: Patent {

    constructor(name: String, id: Int, dept: String): super(name, id) {
        print("execute child class constructor with property $name, $id, $dept")
    }
}
fun main(args: Array<String>) {
val child = Child("Ashu", 101, "Developer")
}

输出:

execute super constructor Ashu: 101
execute child class constructor with property Ashu, 101, Developer

在上面的示例中, 创建Child类的对象时, 它将调用其构造函数并使用值“ Ashu”, “ 101”和“ Developer”初始化其参数。同时, Child类构造函数使用具有name和id值的super关键字调用其超级类构造函数。由于存在super关键字, 因此超类构造函数的主体首先执行, 然后返回Child类构造函数。

Kotlin方法覆盖

方法覆盖是指将父(父)类的方法的特定实现提供到其子类(子)类。

换句话说, 当子类将其超类的方法重新定义或修改为子类时, 称为方法重写。方法重写只能在继承中进行。

Kotlin方法重写规则

  • 父类及其要重写的方法或属性必须是开放的(非最终的)。
  • 基类和派生类的方法名称必须相同。
  • 方法必须具有与基类相同的参数。

不覆盖的继承示例

open class Bird {
    open fun fly() {
println("Bird is flying...")
    }
}
class Parrot: Bird() {

}
class Duck: Bird() {

}
fun main(args: Array<String>) {
val p = Parrot()
    p.fly()
val d = Duck()
    d.fly()
}

输出:

Bird is flying...
Bird is flying...

在上面的示例中, 一个没有覆盖基类方法的程序, 我们发现派生类Parrot和Duck都执行相同的通用操作。为了克服这个问题, 我们使用方法覆盖的概念。

Kotlin方法重载示例

在此示例中, 父类Bird的fly()方法在其子类Parrot和Duck中被覆盖。要覆盖父类的方法, 必须将要覆盖的父类及其方法声明为open。同时, 在子类中被覆盖的方法必须以关键字override作为开头。

open class Bird {
    open fun fly() {
println("Bird is flying...")
    }
}
class Parrot: Bird() {
    override fun fly() {
println("Parrot is flying...")
    }
}
class Duck: Bird() {
    override fun fly() {
println("Duck is flying...")
    }
}
fun main(args: Array<String>) {
val p = Parrot()
    p.fly()
val d = Duck()
    d.fly()
}

输出:

Parrot is flying...
Duck is flying...

Kotlin属性覆盖的示例

与方法类似, 超类的属性也可以在其子类中被覆盖。 Bird类的color属性在其子类Parrot和Duck中被覆盖并进行了修改。

open class Bird {
    open var color = "Black"
    open fun fly() {
println("Bird is flying...")
    }
}
class Parrot: Bird() {
    override var color = "Green"
    override fun fly() {
println("Parrot is flying...")
    }
}
class Duck: Bird() {
    override var color = "White"
    override fun fly() {
println("Duck is flying...")
    }
}
fun main(args: Array<String>) {
val p = Parrot()
    p.fly()
println(p.color)
val d = Duck()
    d.fly()
println(d.color)
}

输出:

Parrot is flying...
Green
Duck is flying...
White

我们可以在继承中使用var属性覆盖val属性, 但反之亦然。

Kotlin超类实现

派生类也可以使用super关键字调用其超类方法和属性。

例如:

open class Bird {
    open var color = "Black"
    open fun fly() {
println("Bird is flying...")
    }
}
class Parrot: Bird() {
    override var color = "Green"
    override fun fly() {
        super.fly()
println("Parrot is flying...")

    }
}

fun main(args: Array<String>) {
val p = Parrot()
    p.fly()
println(p.color)

}

输出:

Bird is flying...
Parrot is flying...
Green

Kotlin多类实施

在Kotlin中, 派生类在实现多个类中提供的相同函数名称时, 在尖括号中使用超类名称, 例如gsuper <Base>。

例如, 派生类Parrotextends其超类Bird并实现包含相同函数fly()的Duck接口。要调用每个类和接口的特定方法, 我们必须在尖括号中提及每个类型的超类型名称分别为super <Bird> .fly()和super <Duck> .fly()。

open class Bird {
    open var color = "Black"
    open fun fly() {
println("Bird is flying...")
    }
}
interface Duck {
     fun fly() {
println("Duck is flying...")
    }
}
class Parrot: Bird(), Duck {
    override var color = "Green"
    override fun fly() {
        super<Bird>.fly()
        super<Duck>.fly()
println("Parrot is flying...")

    }
}
fun main(args: Array<String>) {
val p = Parrot()
    p.fly()
println(p.color)

}

输出:

Bird is flying...
Duck is flying...
Parrot is flying...
赞(0)
未经允许不得转载:srcmini » Kotlin继承

评论 抢沙发

评论前必须登录!