- 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.
- 基于粒計算模型的圖像處理
- Apache ZooKeeper Essentials
- Angular UI Development with PrimeNG
- Access 數(shù)據(jù)庫應(yīng)用教程
- VMware vSphere 6.7虛擬化架構(gòu)實戰(zhàn)指南
- Java程序設(shè)計與實踐教程(第2版)
- Getting Started with Greenplum for Big Data Analytics
- Internet of Things with ESP8266
- HTML+CSS+JavaScript網(wǎng)頁設(shè)計從入門到精通 (清華社"視頻大講堂"大系·網(wǎng)絡(luò)開發(fā)視頻大講堂)
- Hands-On Neural Network Programming with C#
- HTML+CSS+JavaScript網(wǎng)頁制作:從入門到精通(第4版)
- NGUI for Unity
- Java EE輕量級解決方案:S2SH
- HTML5+CSS+JavaScript深入學(xué)習(xí)實錄
- Python深度學(xué)習(xí):基于PyTorch