Kotlin的集体代表团

TL; DR你很好,你可以跳过这篇文章。

在我们开始之前,让我们看看Kotlin中的类授权情况:

界面Flyable {
有趣的飞()
} interface Movable {
有趣的移动()
}类飞机(
liftMechanism:可飞行,
推进力:可动
):可通过liftMechanism飞行,可通过推进移动

那么这段代码有什么用呢?该类代表一种能够移动和飞行的飞行器。现在,这可以通过层次结构完成,对吧?那么为什么要经历所有麻烦并使用委托来定义呢?支撑自己因为我们将在本文中讨论这一切。

等级制度

如果您来自Java或其他早期语言,您可能对继承有很好的了解。为了定义模型,我们通常会找到它们之间的共性以定义基类,然后我们基于差异定义派生类,从而创建类层次结构。

简单地说,我们试图根据模型定义一个家谱。例如,飞行器是移动和飞行的飞行器,而滑翔机将是在没有任何发动机的情况下移动的飞行器。所以你以某种方式定义你的模型:

界面飞机{
有趣的飞()
有趣的移动()
接口WingedAircraft:飞机{
覆盖乐趣fly()= print(“调整翼角……”)
}界面RotorCraft:飞机{
覆盖乐趣fly()= print(“开始旋转刀片……”)
} interface UnpoweredVehicle:Aircraft {
覆盖乐趣move()= print(“只是挂在这里..”)
}接口PropelledVehicle:飞机{
覆盖乐趣move()= print(“启动引擎..”)
}

然后我们可以派生出这样的类:

类滑翔机:WingedAircraft,UnpoweredVehicle
类Jet:WingedAircraft,PropelledVehicle
Gyroglider类:RotorCraft,UnpoweredVehicle
直升机:RotorCraft,PropelledVehicle

到目前为止如此熟悉吧?借助具有默认实现的接口,我们可以在Kotlin中创建类似多重继承的东西。这确实很好;那么班级代表团还有什么问题需要解决吗?还有空间需要改进吗?要看到这一点,首先我们必须深入了解层次结构。

通过继承的多态性

那么继承是什么呢?它是多态的,它使您能够通过它是什么或从中派生什么来定义类。因此,如果一个类派生于Jet,那么它就是一架喷气式飞机,它现在基于它是什么,它可以从喷气机演变为战斗机或无人机。这很好但是你要在哪个级别添加这个新特性?哪些实体是你的父母?喷射?翼和推进?

你最终可能会得到这样一个类:

战斗机:WingedAircraft,PropelledVehicle,CombatAircraft

,而其他人最终会这样

战斗机:Jet()

,和其他人(绝对不是我)可能会这样结束

战斗机:飞机

如你所见,我们已经在看一棵家谱。

问题

因此,让我们通过引入一个问题来改变我们的生活。假设我们想要添加一种新型的飞行机制。

接口AerostatsAircraft:Aircraft {
覆盖乐趣fly()= print(“Start floating ..”)
}

现在我们可以使用像气球一样的热空气飞行的飞机。当然,这些飞机如何移动定义他们的父母:

class Balloon:AerostatsAircraft,UnpoweredVehicle
齐柏林飞艇:AerostatsAircraft,PropelledVehicle

因此,通过引入一个新类型,子类的数量从4增加到6,现在这不是简单更改的合理复杂性,另一个推进类型会将子类的数量从6增加到9,之后只有变得更糟,单独引入一个新的特性,比如飞机如何驾驶会增加两倍的复杂性。所以这里我们需要另一种方式来建模我们的系统。

通过组合的多态性

组合只是通过其行为定义实体的行为。它确实变得更加容易,因为你通过查看它所拥有的组件来创建一个类,而不是考虑它是什么(无论上下文是一个难题)。例如,您可以根据飞机的飞行方式定义飞机:

界面Flyable {
有趣的飞()
}类FixedWing:Flyable {
覆盖乐趣fly()= print(“调整翼角……”)
} class RotaryWing:Flyable {
覆盖乐趣fly()= print(“开始旋转刀片……”)
} class Aircraft(private val liftMechanism:Flyable):Flyable {
覆盖乐趣fly(){
liftMechanism.fly()
}
}

或者你可以根据它的移动方式来定义它:

interface Movable {
有趣的移动()
} class Unpowered:Movable {
覆盖乐趣move()= print(“只是挂在这里..”)
} class Propelled:Movable {
覆盖乐趣move()= print(“启动引擎..”)
}类飞机(私人val推进:可移动):Movable {
覆盖乐趣move(){
propulsion.move()
}
}

现在把它扩展到你可以简单说的每架飞机:

班级飞机(
私人val lift机制:可飞行,
私人val推进:可移动
):可飞行,可移动{

覆盖乐趣fly(){
liftMechanism.fly()
}

覆盖乐趣move(){
propulsion.move()
}
}

现在我们已经建造了我们的飞机让我们看看添加新型飞行机制如何影响我们的班级:

class HotAir:Flyable {
覆盖乐趣fly()= print(“Start floating ..”)
} val balloon = Aircraft(HotAir(),Unpowered())
val zeppelin =飞机(HotAir(),Propelled())

没那么多,是吗?我们在这里所做的是通过定义类的特征来构建类来展平层次结构树。它毕竟是相同的多态性和接口;改变的不是我们使用的技术,而是我们思考的方式。

科特林班级代表团

那么Kotlin做什么?它提供了一个语言关键字,因此您可以跳过所有无聊的部分:

班级飞机(
liftMechanism:可飞行,
推进力:可动
):可通过liftMechanism飞行,可通过推进移动

Kotlin级别的代表团绝不是魔术,它只是一种合成糖(我很欣赏)而不是构图,这使得构图更快更容易。如果有什么东西值得被称为魔术它的组成本身,这使生活和编程更容易。

免责声明:本文不是继承和组合之间的比较,因为有很多关于组合而不是继承的好资源,但这不是其中之一。

资讯来源:由0x资讯编译自HACKERNOON。版权归作者所有,原文链接:https://hackernoon.com/kotlin-what-is-class-delegation-all-about-683eb543e391?source=collection_category—4——0———————。未经许可,不得转载
提示:投资有风险,入市需谨慎,本资讯不作为投资理财建议。请理性投资,切实提高风险防范意识;如有发现的违法犯罪线索,可积极向有关部门举报反映。
你可能还喜欢