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

Lio*_*-On 31 abstract-class kotlin

我知道Kotlin中抽象类和接口之间的两个区别:

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

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

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

interface Shiny {

    fun shine(amount : Int)  // abstract function

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

}
Run Code Online (Sandbox Code Playgroud)

有人能提供一个强有力的实例来说明抽象类的需求吗?

hot*_*key 18

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

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

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

例:

interface MyContainer {
    var size: Int

    fun add(item: MyItem) { 
        // ...
        size = size + 1
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们add为该增量提供默认实现size.但是如果实现类定义如下,它可能会破坏:

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

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

除此之外,抽象类可以有非公共API(内部,受保护)和最终成员,而接口不能(它们只能有私有成员,可以在默认实现中使用),并且所有默认实现都可以被覆盖在课堂上.


小智 0

抽象类本质上是为了类的层次结构而存在的。例如,如果抽象父类具有在扩展父类的子类中也定义的具体函数,则在某些情况下有必要调用父类的函数。当您使用接口时,由于类的完全抽象性质,这是不可能的。

  • **这不是真的**:在 Kotlin 中,如果一个接口提供了默认实现,则实现类可以使用 `super.f()` 调用该实现,请参阅 [**这个可运行的演示**](https:// /try.kotlinlang.org/#/UserProjects/5kt4plrlprfagq4me2ukjocph7/gc3nl1um36ouh7g592qnb0c6qb) (3认同)