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

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

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

既然Kotlin是一个相当新鲜的语言,我想知道为什么抽象类不会被抛弃? 接口看起来很好用,对抽象类很少需要。

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

 interface Shiny { fun shine(amount : Int) // abstract function fun reflect(s : String) { print ("**$s**") } // concrete function } 

有人可以提供一个强大的抽象类的实例吗?

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

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

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

例:

 interface MyContainer { var size: Int fun add(item: MyItem) { // ... size = size + 1 } } 

在这里,我们提供了一个默认的实现来增加size增量。 但是如果一个实现类被这样定义,它可能会中断:

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

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

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

抽象类主要存在于类的层次结构中。 例如,如果抽象的父类有一个具体的函数,这个函数也是在扩展父类的子类中定义的,那么在某些情况下,就需要调用父类的函数。 当你使用一个接口时,由于类的完全抽象性质,这是不可能的。