Kotlin:为什么要使用抽象类(与接口相比)?

时间:2017-08-10 14:29:48

标签: kotlin abstract-class

我意识到Kotlin中抽象类和接口之间存在两个区别:

  • 抽象类可以具有状态(例如var ...)
  • 一个类可以实现多个接口,但不能实现多个抽象类。

由于Kotlin是一种相当新鲜的语言,我想知道为什么抽象类没有被抛弃?接口似乎是优秀的工具,对Abstract Classes的需求很少。

详细说明:Kotlin支持接口中的具体功能实现,例如:

interface Shiny {

    fun shine(amount : Int)  // abstract function

    fun reflect(s : String) { print ("**$s**") }  // concrete function

}

有人能提供一个强有力的实例,说明是否需要抽象类?

3 个答案:

答案 0 :(得分:13)

抽象类的实际方面是,您可以封装与状态一起使用的实现的一部分,以便它不能在派生类中重写。

在接口中,您只能定义没有支持字段的属性,并且实现类必须覆盖该属性(使用支持字段或自定义访问器)。

鉴于此,您无法定义以可靠方式在接口中存储某些状态的逻辑:实现类可能会以意外方式覆盖属性。

示例:

interface MyContainer {
    var size: Int

    fun add(item: MyItem) { 
        // ...
        size = size + 1
    }
}

在此,我们为add提供了一个增量size的默认实现。但如果实现类定义如下,它可能会破坏:

class MyContainerImpl : MyContainer {
    override val size: Int 
        get() = 0
        set(value) { println("Just ignoring the $value") }
}

相反,抽象类支持这个用例,因此允许你为它们的所有实现提供一些保证和契约:它们可以定义一些状态及其在派生类中保持相同的转换。

除此之外,抽象类可以有非公共API(内部,受保护)和最终成员,而接口不能(它们只能有私有成员,可以在默认实现中使用),以及它们的所有默认实现可以在课程中重写。

答案 1 :(得分:1)

抽象类主要存在于类的层次结构中。例如,如果抽象父类具有在子类中定义的具体函数,该子类扩展了父类,那么在某些情况下,有必要调用父函数。当您使用界面时,由于该类的完全抽象性,不可能这样做。

答案 2 :(得分:-1)

区别之一是,如果将其作为接口,我们可以将多个接口继承到一个类,但对于抽象类,只能将单个抽象类继承到一个类(只有一个类出现在超类型列表中)

>

快乐编码!!!