Kotlin oops classes & Inheritance Tutorials

      No Comments on Kotlin oops classes & Inheritance Tutorials

Inheritance is fundamental to object-oriented programming. It allows us to create new classes that reuse, extend, and/or modify the behavior of the preexisting ones. The preexisting class is called the super class, and the brand new class we are creating is called the derived class. There is a restriction on how many super classes we can inherit from; on a JVM, you can only have one base class. But you can inherit from multiple interfaces. Inheritance is transitive. If class C is derived from class B and that class B is derived from a given class A, then class C is a derived class of A.

A derived class will implicitly get all the parent classes (and the parent’s parent class, if that is the case) fields, properties, and methods. The importance of inheritance lies in the ability to reuse code that has already been written and therefore avoid the scenario where we would have to re-implement the behavior exposed by the parent class. A derived class can add fields, properties, or new methods, thus extending the functionality available through the parent. We would say that class B, the derived one, specializes class A, the parent. A simpler example is to think of the animal kingdom chart. At the top, we have animal,followed by vertebrates and invertebrates; the former is further split into fish, reptile,mammals, and so on. If we take the yellow-fin tuna species, we can look at it as a specialized type of fish.

Let’s implement the preceding code and see how we actually define in Kotlin inheritance:

   enum class CardType {
      VISA, MASTERCARD, AMEX
    }
    open class Payment(val amount: BigDecimal)
    class CardPayment(amount: BigDecimal, val number: String, val
expiryDate: DateTime, val type: CardType) : Payment(amount)

We have created our classes based on the spec we just saw. Card-type is an enumeration type, as hinted in the definition. The definition of Payment has introduced a new keyword, called open . Through this keyword, you are basically saying the class can be inherited from.The designers of Kotlin tutorial have decided the default behavior is to have the classes sealed for inheritance. If you have programmed in Java, you will have come across the final
keyword, which does exactly the opposite of open. In Java, any class which hasn’t been marked as final can be derived from. The definition of CardPayment marks the inheritance via a semicolon. The : Payment translates into: “
CardPayment which extends from Payment“. This is different to Java where you would use the extends keyword. Any
developers with C++ or C# background will be very familiar with the construct.

In the preceding code, our CardPayment class has a primary constructor. Therefore, the parent one has to be called on the spot, hence Payment(amount). But what if our new class doesn’t define a primary constructor? Let’s extend our class hierarchy to add a new type, named ChequePayment:

  class ChequePayment : Payment {
      constructor(amount: BigDecimal, name: String, bankId: String) :
super(amount) {
        this.name = name
        this.bankId = bankId
      }
      var name: String
        get() = this.name
      var bankId: String
        get()  = this.bankId
    } 

,

Since we have chosen to avoid the primary constructor, the definition of a secondary constructor has to call the parent one. This call needs to be the first thing our constructor does. Hence, the body of our constructor is preceded by super(args1,args2… . This is different from Java, where we would have moved this call as the first line in our constructor body.

In this example we inherit from one class only – as we said already we can’t inherit from
more than one class. However, we can inherit from multiple interfaces at the same time. Let’s take a simple example of an amphibious car: it is a boat as well as a car. If you were to model this, we would consider having two interfaces: Drivable and Sailable. And we would have our amphibious car extend both of them:

   interface Drivable {
      fun drive()
    }
    interface Sailable {
      fun saill()
    }
    class AmphibiousCar(val name: String) : Drivable, Sailable {
      override fun drive() {
        println("Driving...")
     }
      override fun saill() {
        println("Sailling...")
      }
    } 

Remember our class automatically derives from Any; it is as if we had written class AmphibiousCar(val name:String):Any, Drivable, Sailable . When we inherit an interface, we have to provide an implementation for all its methods and properties or we have to make the class abstract. We will talk shortly about abstract classes. There is no restriction on how many interfaces you can inherit from and the order in which you want to specify them. Unlike Java, if you inherit from a class and one or more interfaces, you don’t need to list the class as the first entry in the list of parents:

  interface IPersistable {
      fun save(stream: InputStream)
    }
    interface IPrintable {
      fun print()
    }
    abstract class Document(val title: String)
    class TextDocument(title: String) : IPersistable, Document(title),
IPrintable {
  override fun save(stream: InputStream) {
        println("Saving to input stream")
      }
      override fun print() {
        println("Document name:$title")
      }
    } 

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn