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

Overriding rules

You decided your new class has to redefine one of the methods inherited from one of the parent classes. This is known as overriding; I have already used it in Chapter 2, Kotlin Basics. If you have already programmed in Java, you will find Kotlin a more explicit language. In Java, every method is virtual by default; therefore, each method can be overridden by any derived class. In Kotlin, you have to tag the function as being opened to redefine it. To do so, you need to add the open keyword as a prefix to the method definition, and when you redefine the method, you specifically have to mark it using the override keyword:

    abstract class SingleEngineAirplane protected constructor() { 
      abstract fun fly() 
    } 
 
    class CesnaAirplane : SingleEngineAirplane() { 
     override fun fly() { 
       println("Flying a cesna") 
     } 
   } 

You can always disallow any derived classes from overriding the function by adding the final keyword in front of the method. Using the previous example, we don't want any of the Cesna models to redefine the method:

    class CesnaAirplane : SingleEngineAirplane() { 
      final override fun fly() { 
        println("Flying a cesna") 
      } 
    } 

You are not limited to functions only. Since Kotlin borrows the concept of properties from C#, you can also mark properties as virtual:

    open class Base { 
      open val property1: String 
        get() = "Base::value" 
    } 
    class Derived1 : Base() { 
      override val property1: String 
       get() = "Derived::value" 
    } 
    class Derived2(override val property1: String) : Base() {} 

You can override a val property with var if your coding logic requires this, but the reverse is not possible:

    open class BaseB(open val propertyFoo: String) {
    }

    class DerivedB : BaseB("") {
      private var _propFoo: String = ""
      override var propertyFoo: String
      get() = _propFoo
      set(value) {
        _propFoo = value
      }
    }

    fun main(args: Array<String>) {
      val baseB = BaseB("BaseB:value")
      val derivedB= DerivedB()
      derivedB.propertyFoo = "on the spot value"
      println("BaseB:${baseB.propertyFoo}")
      println("DerivedB:${derivedB.propertyFoo}")
    }

There are scenarios where you need to derive from one class and at least one interface and both define and implement a method with the same name and parameters. In such cases, the inheritance rule forces you to override the method. If you create a new instance of your object and call the method that is common to the immediate parent classes, which one should the compiler link to? Therefore, you need to remove ambiguity and provide the implementation; it could use any or both the parent class implementations. Imagine you have a class hierarchy for dealing with different image formats and you want to unify them with a third-party hierarchy. Since both class hierarchies come with a definition of the save function, you would need to override them:

    open class Image { 
      open fun save(output: OutputStream) { 
        println("Some logic to save an image") 
      } 
    } 
    interface VendorImage { 
      fun save(output: OutputStream) { 
        println("Vendor saving an image") 
      } 
    } 
    class PNGImage : Image(), VendorImage { 
      override fun save(output: OutputStream) { 
        super<VendorImage>.save(output) 
        super<Image>.save(output) 
      } 
    } 
 
    fun main(args: Array<String>) { 
      val pngImage = PNGImage() 
      val os = ByteArrayOutputStream() 
      pngImage.save(os) 
    } 

The overriding is not enforced if the VendorImage interface has not provided an implementation. Referencing the parent implementation is done through super<PARENT>, as you might have already noticed in the implementation earlier.

主站蜘蛛池模板: 泰来县| 喜德县| 南丰县| 永修县| 千阳县| 舒兰市| 龙川县| 尚志市| 韩城市| 平湖市| 灌云县| 周宁县| 垦利县| 永泰县| 普洱| 河东区| 昔阳县| 同心县| 汝州市| 托克托县| 任丘市| 拉孜县| 连州市| 惠东县| 铅山县| 通化市| 修文县| 文成县| 治多县| 南京市| 金堂县| 璧山县| 阜南县| 类乌齐县| 北海市| 保靖县| 太湖县| 英吉沙县| 甘肃省| 湖南省| 孝昌县|