无法理解 Java/Kotlin 中的抽象

Unable to understand Abstraction in Java/Kotlin

我很难理解抽象的概念。根据定义,抽象 是隐藏某些细节并仅向用户 显示来自 w3schools 的基本信息的过程。 下面是我的 class -

open class SimpleClass {
    fun engine() {}
}

class ChildSimpleClass : SimpleClass()

abstract class AbstractClass {
    abstract fun engine()
}

class AbstractClassImpl : AbstractClass() {
    override fun engine() {}
}

interface Interface {
    fun engine()
}

class InterfaceImpl : Interface {
    override fun engine() {}
}

fun main(){
    //first case
    val simpleClass: SimpleClass  = ChildSimpleClass()
    simpleClass.engine()

    //second case
    val abstractClassImpl:AbstractClass = AbstractClassImpl()
    abstractClassImpl.engine()

    //third case
    val interfaceImpl: Interface = InterfaceImpl()
    interfaceImpl.engine()
}  

1.Does第一种情况是否符合抽象条件?

2.If 是的,那为什么我们说我们使用“接口和抽象classes”实现抽象,为什么不使用普通的classes?来自 here 和我浏览过的许多其他来源

3.If 不,那么为什么它不符合抽象条件,因为我的 class 只知道 ChildSimpleClass 而不知道 SimpleClass 这不是隐藏了关于 SimpleClass 的细节吗?

你有多种选择来进行抽象。第一个选择必须是接口,因为你可以实现多个接口,但不能超过一个 class。例如,您可以有一个 class 来实现 DriverEater 接口。但不能用 classes 做到这一点。然后你可以使用你的 class 的实例作为任何一个。

第二个选择必须是抽象的classes。抽象 class 和接口之间的区别在于状态。 abstract classes 可以有状态。如果你在抽象中需要状态,你应该考虑使用 abstract classes。例如 Driver 可能不需要状态,但 Car 可能需要它知道它是否已启动(完全取决于您的要求)

开放 class 的问题是您不能 force subclasses 来实现方法。而且你总是需要为你的方法实现。

此外,抽象不仅仅是隐藏细节。它还与为您的 class 设置规则有关。例如 class Engine 应该总是有一个名字,并且随着引擎类型的改变而改变。和一个基于名称工作的 start() 方法:

abstarct class Engine {

    var isStarted = false

    abstract val name: String

    fun start() {
        isStarted = true
        println("engine $name started")
    }
}

所以只要你不能用开放的 classes 定义规则,你就不应该认为它是一个抽象。但正如 Tenfour04 在评论中所说,这只是关于抽象一词的语义争论。但了解其中的区别很重要。