Interface inheritance
Interface inheritance

Interface inheritance

提供方: JetBrains 学院

继承是我们之前在讨论类时已经介绍过的一个概念。它通过引入创建类扩展(甚至是类模型或抽象)的方法,极大地减少了样板代码的数量,这些扩展可以在以后实现。

当我们需要某个类继承另一个类的属性并扩展它的功能,而无需重复编写代码时,就可以使用继承。简而言之,当我们需要创建的类与已有的类有一些共同之处时,继承就非常有用。

接口继承

同样的模式也适用于接口,但它们更进一步。Kotlin 中的类不能继承多个,但它们可以实现多个接口(类可以继承基类,而基类又可以继承另一个类,但这与的一般概念并不完全相同)。

类和语法相同:新接口的名称放在冒号 ( : ) 之前,位于 interface 关键字之后;冒号之后是基接口的名称——新接口继承其属性的接口:

interface Animal {
    val amountOfLimbs: Int
    fun move()
    fun communicate()
}

interface Bird : Animal {
    val canFly: Boolean
    val flyingSpeed: Int
    fun buildNest()
}

在这个例子中,由于鸟类具有一些动物的属性和特征,因此 Bird 接口是从 Animal 接口派生而来,同时添加了一些它自己的方法和属性。

派生接口的实现

实现派生接口的主要规则是,类必须同时实现基接口和派生接口中的方法和属性:

interface Animal {
    val numberOfLimbs: Int
    fun move()
    fun communicate()
}

class Parrot : Bird // : Animal
{
    // These properties are inherited from the Animal interface...
    override val numberOfLimbs: Int = 2

    override fun move() {
        fly()
    }

    override fun communicate() {
        speak()
    }

    // ...while these ones are specifically from the Bird interface

    override val canFly: Boolean = true

    override val flyingSpeed: Int = 20

    override fun buildNest() {
        collectMaterials()
        findGoodPlace()
        buildSmallNest()
    }
}

在这个例子中, Parrot 是一种鸟,而鸟是一种动物,所以 Parrot 既具有 Bird 的特征,又具有 Animal 的特征。

多重继承

然而,这并非实现具有多个接口特征的鸟类实例的唯一方法。我们还可以利用 多重继承 :一个类可以实现多个不同的接口。

在这里,我们将鸟类的 Flying 特性分离到另一个接口中。在实际模拟中,这样做的一个合理理由是,鸟类并非唯一能够飞行的生物,因此我们可以让 Insect 类(或接口)也实现 Flying 接口。

interface Bird : Animal {
    fun buildNest()
}

interface Flying {
    val flyingSpeed: Int
    val flyingManeuverability: Int
}

class Owl : Bird, Flying {

    // Flying interface
    override val flyingSpeed: Int = 100
    override val flyingManeuverability: Int = 95

    // Bird interface
    override fun buildNest() {
        buildSmallNest()
    }

    // Animal Interface
    override val numberOfLimbs: Int = 2

    override fun move() {
        fly()
    }

    override fun communicate() {
        coo()
    }

}

// Reusing the Flying interface
interface Insect : Flying
{
    // ...
}

class Fly : Insect, Animal {
    // ...
}

然而,有时当一个类实现多个接口时,我们可能会遇到它继承了同一个方法或属性的多个实现的情况。这会导致冲突,我们将在下一节讨论如何解决这些冲突。

继承自多个接口

就像类可以实现多个接口一样,一个接口也可以派生自多个其他接口。

interface FlyingBird : Bird, Flying  
{  
    /* ... */  
}

那么我们的 Owl 类看起来就会像这样:

class Owl : FlyingBird {  

 // FlyingBird interface, derived from Flying
 override val flyingSpeed: Int = 100  
 override val flyingManeuverability: Int = 95  

 // FlyingBird interface, derived from Bird
 override fun buildNest() {  
        buildSmallNest()  
    }

    /* ... */

}

结论

现在你知道,继承作为程序员工具箱中的一项重要工具,不仅可以应用于类,还可以应用于接口,从而构建更加复杂的结构或层次。我们不仅可以从一个接口继承,而这个接口本身又可以继承自另一个接口,而且我们还可以做一些仅使用类无法实现的事情——例如同时从多个接口继承属性——这就像创建一个用逗号分隔的列表一样简单。

99 名学员喜欢这篇理论文章, 1 名学员不喜欢。 你呢?

报告拼写错误

相关条目

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注