Search code examples
javakotlinoopabstract-classabstraction

Unable to understand Abstraction in Java/Kotlin


I have difficulty understanding the concept of Abstraction. By definition abstraction is the process of hiding certain details and showing only essential information to the user from w3schools. So below is my 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 the first case qualify to be abstraction ?

2.If yes, then why do we say we achieve abstraction using "interfaces and abstract classes" and why not using normal classes ? from here and many other sources which I went through

3.If not, then why does it not qualify to be abstraction as my class only knows about ChildSimpleClass and not about the SimpleClass is this not hiding details about SimpleClass ?


Solution

  • you have multiple choices to do abstraction with. the first choice must be interface because you can implement multiple interfaces but not more than one class. for example, you can have a class that implements both a Driver and an Eater interface. but can't do that with classes. and then you can use an instance of your class as either one.

    the second choice must be abstract classes. the difference between an abstract class and an interface is state. abstract classes can have state. and if you need state in your abstraction you should consider using abstract classes. for example a Driver might not need state, but a Car might need it to know if it's started or not(totally depends on your requirements)

    the problem with an open class is that you can't force subclasses to implement a method. and also you always need to have implementations for your methods.

    also, abstraction is not only about hiding details. it's also about setting rules for your class. for example a class Engine should always have a name and that changes when the type of engine changes. and a start() method that works based on name:

    abstarct class Engine {
    
        var isStarted = false
    
        abstract val name: String
    
        fun start() {
            isStarted = true
            println("engine $name started")
        }
    }
    

    so as long as you can't define rules with open classes, you should not consider it an abstraction. but as Tenfour04 said in comments, This is just a semantic argument about the word abstraction. but it's important to know the difference.