Instruction

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Abstract Classes

Sometimes, you may want to prevent a class from being instantiated but still be able to be inherited from. This will let you define properties and behavior common to all subclasses. Such a parent class is called an abstract class. These classes can’t be instantiated, meaning you can’t create an object of an abstract class. You can think of these classes as templates for other classes. Templates, as you know them, are just base style, configurations, and functionality guidelines for a specific design. The template can’t run directly on your website or app. Instead, your app can make use of the template.

abstract class Animal {
  abstract val name: String // Abstract Property
}

abstract class Mammal(val birthDate: String): Animal() { // Non-Abstract Property (birthDate)
  abstract fun consumeFood() // Abstract Method

  abstract val furColor: List<String> // Abstract Property

  // Non-Abstract Method
  fun someMammalMethod() {
    println("Non abstract function")
  }
}

class Human(birthDate: String): Mammal(birthDate) {
  // Abstract Property (Must be overridden by Subclasses)
  override val name = "Human"

  // Abstract Property (Must be overridden by Subclasses)
  override val furColor = listOf("brown", "black")

  // Abstract Method (Must be implemented by Subclasses)
  override fun consumeFood() {
    // ...
  }

  // Member method created by this class (Not Inherited)
  fun createBirthCertificate() {
    // ...
  }
}
val human = Human("1/1/2000")
val mammal = Mammal("1/1/2000") // Error: Cannot create an instance of an abstract class

Using Interfaces

So far, we’ve been working with the custom type, Class. You’ve learned about inheritance and how a class can extend an abstract and non-abstract class that are related. Another very useful custom type is Interfaces.

interface Pluggable {

  val neededWattToWork: Int // properties in interfaces cannot maintain state
  // val neededWattToWork: Int = 40 // this won't work. would result in an error because of the reason above

  //Measured in Watt
  fun electricityConsumed(wattLimit: Int) : Int

  fun turnOff()

  fun turnOn()
}

class Microwave : Pluggable {

  override val neededWattToWork = 15

  override fun electricityConsumed(wattLimit: Int): Int {
    return if (neededWattToWork > wattLimit) {
      turnOff()
      0
    } else {
      turnOn()
      neededWattToWork
    }
  }

  override fun turnOff() {
    println("Microwave Turning off...")
  }

  override fun turnOn() {
    println("Microwave Turning on...")
  }
}

class WashingMachine : Pluggable {

  override val neededWattToWork = 60

  override fun electricityConsumed(wattLimit: Int): Int {
    return if (neededWattToWork > wattLimit) {
      turnOff()
      0
    } else {
      turnOn()
      neededWattToWork
    }
  }

  override fun turnOff() {
    println("WashingMachine Turning off...")
  }

  override fun turnOn() {
    println("WashingMachine Turning on...")
  }
}
fun turnOn() {
  println("Turning on...")
}
val washingMachine = WashingMachine()
washingMachine.turnOn() // Turning on...

Using Kotlin Standard Library Interfaces

The Kotlin standard library provides us with some interfaces and ready-made tools that help with common functionalities. This helps us avoid reinventing the wheel when we want to do some basic operations or when we want a class to abide by a specific contract. One of them is the Comparable interface.

See forum comments
Download course materials from Github
Previous: Introduction Next: Demo