- Learn Kotlin Programming(Second Edition)
- Stephen Samuel Stefan Bocutiu
- 546字
- 2021-06-24 14:13:34
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.
- CMDB分步構建指南
- Linux C/C++服務器開發實踐
- Instant 960 Grid System
- 劍指大數據:企業級數據倉庫項目實戰(在線教育版)
- Learning Concurrency in Kotlin
- Mastering Business Intelligence with MicroStrategy
- Solr Cookbook(Third Edition)
- Android項目實戰:手機安全衛士開發案例解析
- ArcGIS for Desktop Cookbook
- Buildbox 2.x Game Development
- Python網絡爬蟲技術與應用
- Natural Language Processing with Python Quick Start Guide
- Python+Office:輕松實現Python辦公自動化
- Mastering Concurrency in Python
- C#面向對象程序設計(第2版)