функция расширения является виртуальной для отправки получателя? - PullRequest
1 голос
/ 01 марта 2020

In kotlin Объявление расширений как членов , что означает "отправка таких функций виртуальная в отношении отправки тип получателя, но stati c относительно типа получателя расширения. "

Это означает, что " функция расширения не соответствует классу своего получателя тип. Это следует за типом параметра (? в этом параметре метода вызова кода). "

, пожалуйста, дайте сердечный и щедрый совет

open class Base { }

class Derived : Base() { }

open class BaseCaller {
    open fun Base.printFunctionInfo() {
        println("Base extension function in BaseCaller")
    }

    open fun Derived.printFunctionInfo() {
        println("Derived extension function in BaseCaller")
    }

    fun call(b: Base) {
        b.printFunctionInfo()   // call the extension function
    }
}

class DerivedCaller: BaseCaller() {
    override fun Base.printFunctionInfo() {
        println("Base extension function in DerivedCaller")
    }

    override fun Derived.printFunctionInfo() {
        println("Derived extension function in DerivedCaller")
    }
}

fun main() {
    BaseCaller().call(Base())   // "Base extension function in BaseCaller"
    DerivedCaller().call(Base())  // "Base extension function in DerivedCaller" - dispatch receiver is resolved virtually
    DerivedCaller().call(Derived())  // "Base extension function in DerivedCaller" - extension receiver is resolved statically
}

1 Ответ

2 голосов
/ 01 марта 2020

Поскольку вы связали документацию, я полагаю, что вы прочитали следующую часть

Экземпляр класса, в котором объявлено расширение, называется диспетчер отправки , и экземпляр типа приемника метода расширения называется приемник расширения .

После того, как вы поняли вышеизложенное В терминологии необходимо понимать следующие пункты

  • Если вы не знаете о виртуальных методах, прочитайте this
  • Расширения разрешаются статически . Рассмотрим следующий кодовый блок

    fun call(b: Base) {
         // This will always call extension function defined on the Base class
         // even if you pass an object of Derived class
         b.printFunctionInfo()   // call the extension function
    }
    
    // This calls the printFunctionInfo defined on the Base, even though we pass Derived
    DerivedCaller().call(Derived()) 
    

Теперь к вашему вопросу

отправка таких функций является виртуальной в зависимости от типа получателя отправления, но остается c относительно типа приемника добавочного номера.

С помощью Расширения разрешаются статически Мы установили, что независимо от того, какой объект вы передаете ( Base или Derived) функция call всегда будет вызывать функцию расширения, определенную для типа Base.

Но какая функция расширения будет вызываться ? один в базовом классе или один в производном классе?

Это зависит от типа объекта, который вызывает функцию call, если вы вызываете вызов с помощью Object of Base, тогда расширение в базовом классе будет вызван, и если вы используете объект Derived, то будет вызвано расширение в классе Derived.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...