官术网_书友最值得收藏!

  • Functional Kotlin
  • Mario Arias Rivu Chakraborty
  • 619字
  • 2021-06-24 19:15:21

Inheritance

As we continue modelling our domain in Kotlin, we realize that specific objects are quite similar. If we go back to our HR example, an employee and a contractor are quite similar; both have a name, a date of birth, and so on; they also have some differences. For example, a contractor has a daily rate, while an employee has a monthly salary. It is obvious that they are similar—both of them are people; people is a superset where both contractor and employee belong. As such, both have their own specific features that make them different enough to be classified into different subsets.

This is what inheritance is all about, there are groups and subgroups and there are relationships between them. In an inheritance hierarchy, if you go up in the hierarchy, you will see more general features and behaviors, and if you go down, you will see more specific ones. A burrito and a microprocessor are both objects, but they have very different purposes and uses. 

Let's introduce a new Biscuit class:

class Biscuit(val flavour: String) { 
fun eat(): String {
return "nom, nom, nom... delicious $flavour biscuit"
}
}

Again, this class looks almost exactly same as Cupcake. We could refactor these classes to reduce code duplication:

open class BakeryGood(val flavour: String) { 
fun eat(): String {
return "nom, nom, nom... delicious $flavour bakery good"
}
}

class Cupcake(flavour: String): BakeryGood(flavour)
class Biscuit(flavour: String): BakeryGood(flavour)

We introduced a new BakeryGood class, with the shared behavior and state of both Cupcake and Biscuit classes and we made both classes extend BakeryGood. By doing so, Cupcake (and Biscuit) has an is-a relationship with BakeryGood now; on the other hand, BakeryGood is the Cupcake class's super or parent class.

Note that BakeryGood is marked as open. This means that we specifically design this class to be extended. In Kotlin, you can't extend a class that isn't open.

The process of moving common behaviors and states to a parent class is called generalisation. Let's have a look at the following code:

fun main(args: Array<String>) {
val myBlueberryCupcake: BakeryGood = Cupcake("Blueberry")
println(myBlueberryCupcake.eat())
}

Let's try out our new code:

Bummer, not what we were expecting. We need to refract it more:

open class BakeryGood(val flavour: String) { 
fun eat(): String {
return "nom, nom, nom... delicious $flavour ${name()}"
}

open fun name(): String {
return "bakery good"
}
}

class Cupcake(flavour: String): BakeryGood(flavour) {
override fun name(): String {
return "cupcake"
}
}

class Biscuit(flavour: String): BakeryGood(flavour) {
override fun name(): String {
return "biscuit"
}
}

It works! Let's have a look at the output:

We declared a new method, name(); it should be marked as open, because we designed it to be optionally altered in its subclasses.

Modifying a method's definition on a subclass is called override and that is why the name() method in both subclasses is marked as override.

The process of extending classes and overriding behavior in a hierarchy is called specialisation.

Rule of thumb

Put general states and behaviors at the top of the hierarchy (generalisation), and specific states and behaviors in subclasses (specialisation).

Now, we can have more bakery goods! Let's have a look at the following code:

open class Roll(flavour: String): BakeryGood(flavour) { 
override fun name(): String {
return "roll"
}
}

class CinnamonRoll: Roll("Cinnamon")

Subclasses can be extended too. They just need to be marked as open:

open class Donut(flavour: String, val topping: String) : BakeryGood(flavour)
{
override fun name(): String {
return "donut with $topping topping"
}
}

fun main(args: Array<String>) {
val myDonut = Donut("Custard", "Powdered sugar")
println(myDonut.eat())
}

We can also create classes with more properties and methods.

主站蜘蛛池模板: 安丘市| 邢台市| 潮安县| 阳新县| 扶沟县| 三都| 玉山县| 都兰县| 商河县| 陇南市| 敖汉旗| 肥城市| 屏山县| 罗平县| 北安市| 沙洋县| 大埔区| 滦平县| 四子王旗| 华蓥市| 南平市| 宾阳县| 宽城| 甘孜| 石景山区| 凤阳县| 都昌县| 嘉善县| 湛江市| 资源县| 阳西县| 临洮县| 望城县| 济宁市| 平陆县| 隆安县| 东乌珠穆沁旗| 蓝山县| 盘山县| 桃江县| 五常市|