Exercises for Lesson 7

Back to Lesson 7

Exercise 1: Inheritance and method calls

The following program defines four classes. Draw a class diagram indicating the relationship between classes, as well as each class’s instance variables, constructor, and other methods.

open class A(v: Int) {
    val myVal: Int = v

    open fun doTheThing() {
        println("In A: $myVal")
    }
}

open class B(v: Int): A(v) {
    override fun doTheThing() {
        println("In B: ${myVal * 2}")
    }
}

class C(v: Int): B(v * 2) { // set myVal differently
}

class D(v: Int, other: Int): A(v) {
    val otherVal: Int = other

    override fun doTheThing() {
        println("In D: ${otherVal * myVal}")
    }
}

fun main() {
    val a = A(4)
    val b = B(22)
    val c = C(201)
    val d = D(10, 7)

    for (obj in listOf(a, b, c, d)) {
        obj.doTheThing()
    }
}

Back to Lesson 7

Exercise 2: Inheritance practice

Part A: Parent class constructor

First, let’s build a class to represent animals. Try to write a class named Animal with following constructor: Animal(name, kind, age), which takes name (a string), kind (a string, like "dog" or "beaver"), and age (an integer, defaulting to 0).

Test your code by making a main function to create two Animal objects. Here is an example:

fun main() {
    val a1 = Animal("Hobbes", "cat", 12)
    val a2 = Animal("Therese", "beaver") // she's a baby!
}

Add a class method getNumLegs to get the number of legs. It should take no parameters, and throw an exception, because a generic animal doesn’t have a set number of legs. Add a call to this method in main and make sure it fails.

Here is an example of throwing an exception:

fun main() {
    print("Please type a string (but NOT 'apple'): ")
    var s: String? = readLine()
    if (s == "apple") {
        throw Exception("Bad input!!")
    } else {
        println("You typed '$s'")
    }
}

Part B: Child classes

Let’s create some child classes that will fix our leg conundrum. Create two classes for different animals and make them subclasses of Animal. Each should call the parent constructor, and include a method to override getNumLegs and return the appropriate value.

For example, you could create a Loon class. Its getNumLegs method may look like this:

    override fun getNumLegs() {
        return 2
    }

What changes do you have to make to the Animal class to make this possible? Also, make sure to add some new Animal-subclass objects to main to test your code.

Part C: New functionality

Add some init blocks to your classes. Have each print something different. Do you see these get executed when you create the objects?

Add some new instance variables and methods to the subclasses. For example, if you added a method sing to a Loon class, what happens if you call a2.sing() on an Animal instance? What about some other instance?

Back to Lesson 7