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

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.

主站蜘蛛池模板: 彝良县| 应城市| 芦溪县| 常熟市| 莆田市| 彭泽县| 庆元县| 阳谷县| 青阳县| 安国市| 浮山县| 耒阳市| 铜陵市| 屏边| 博白县| 镇赉县| 丘北县| 莱芜市| 武冈市| 浪卡子县| 印江| 齐齐哈尔市| 延庆县| 邓州市| 尖扎县| 大余县| 翁源县| 祁连县| 龙胜| 吴桥县| 二连浩特市| 名山县| 邵阳市| 太康县| 郓城县| 富裕县| 丰县| 台东市| 平舆县| 大丰市| 澄城县|