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

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.

主站蜘蛛池模板: 清镇市| 东城区| 松潘县| 高要市| 林州市| 虎林市| 大洼县| 榆社县| 乌拉特后旗| 公安县| 灵山县| 罗山县| 顺平县| 元谋县| 兴安县| 千阳县| 崇仁县| 安吉县| 敦煌市| 慈利县| 炎陵县| 通海县| 罗源县| 平山县| 澄江县| 五台县| 汉阴县| 青浦区| 桐梓县| 西城区| 麻阳| 海南省| 镇安县| 若尔盖县| 陵水| 青龙| 黄梅县| 榆社县| 辽源市| 滕州市| 城市|