- Learn Kotlin Programming(Second Edition)
- Stephen Samuel Stefan Bocutiu
- 467字
- 2021-06-24 14:13:37
Overriding member extension functions
Member extension functions can be declared as open if you wish to allow them to be overridden in subclasses. In this case, the dispatcher receiver type will be virtual; that is, it will be the runtime instance. However, the extension receiver will always be resolved statically.
To demonstrate this, we will create a class called Element, which has a function called react. This function will accept a Particle type:
open class Particle
class Electron : Particle()
open class Element(val name: String) {
fun react(particle: Particle) {
particle.doReaction(name)
}
open fun Particle.doReaction(name: String) {
println("$name is reacting with a particle")
}
open fun Electron.doReaction(name: String) {
println("$name is reacting with an electron to make an isotope")
}
}
You can see that we have two particles – a superclass and a subclass called Electron. When we call the react function, it just delegates to a member extension function called doReaction. Now, let's use this class as follows:
val selenium = Element("Selenium")
selenium.react(Particle())
selenium.react(Electron())
Creating the element and calling react with both a Particle type and an Element class results in the following:
Selenium is reacting with a particle
Selenium is reacting with a particle
As you can see, the extension function defined on Particle was invoked in both cases, even though, at runtime, one of the inputs was an Electron instance. This is because the extension type of a member extension function is always determined at compile time, and at compile time, the type is Particle.
Now, if we extend Element with a subclass called NobleGas, and then add another react method to accept an Electron subclass instead, we have the following:
class NobleGas(name: String) : Element(name) {
override fun Particle.doReaction(name: String) {
println("$name is noble, it doesn't react with particles")
}
override fun Electron.doReaction(name: String) {
println("$name is noble, it doesn't react with electrons")
}
fun react(particle: Electron) {
particle.doReaction(name)
}
}
To be clear, the react method in this subclass is in addition to the react method inherited from the parent class. The subclass has two functions available, one that accepts any Particle type, and one that specifically accepts an Electron type.
If we now run the following code:
val helium = NobleGas("Helium")
helium.react(Particle())
helium.react(Electron())
The output of this function will differ from the previous example as follows:
Helium is noble, it doesn't react with particles
Helium is noble, it doesn't react with electrons
We have seen in this case that the more specific method is invoked. This is because, at runtime, the more specific react function will be invoked – the one added in the subclass. And, since this function declared the input type to be Electron, the extension function determined at compile time was the extension function defined on the Electron type.
- Learning Scala Programming
- Qt 5 and OpenCV 4 Computer Vision Projects
- C語(yǔ)言程序設(shè)計(jì)實(shí)踐教程
- Java Web應(yīng)用開(kāi)發(fā)技術(shù)與案例教程(第2版)
- Effective Python Penetration Testing
- 重學(xué)Java設(shè)計(jì)模式
- Linux命令行與shell腳本編程大全(第4版)
- 量化金融R語(yǔ)言高級(jí)教程
- SQL Server與JSP動(dòng)態(tài)網(wǎng)站開(kāi)發(fā)
- jQuery炫酷應(yīng)用實(shí)例集錦
- Java Web開(kāi)發(fā)就該這樣學(xué)
- Solr Cookbook(Third Edition)
- SQL Server 2008中文版項(xiàng)目教程(第3版)
- Arduino電子設(shè)計(jì)實(shí)戰(zhàn)指南:零基礎(chǔ)篇
- Secret Recipes of the Python Ninja