#kotlin #overriding
Вопрос:
Я думал var
, что это может быть отменено, как val
с единственным получателем, потому что в нем есть как получатель, так и сеттер. Но это невозможно.
И, если переопределить val
, у которого есть только геттер, с var
тем, у которого есть сеттер, ошибка не возникает. Я не знаю, как это возможно.
Почему это так работает?
Ответ №1:
Ваш второй пример (переопределение val
с var
) похож на этот псевдокод:
open class Test {
fun getA()
}
class Main : Test() {
fun setA()
}
Main
подкласс просто добавляет новый метод, нет причин, по которым это было бы невозможно. Ваш первый пример (переопределение var
с val
) будет похож на:
open class Test {
fun getA()
fun setA()
}
class Main : Test() {
// remove setA() function
}
Как вы, наверное, знаете, удалить методы в подклассах невозможно, поэтому их невозможно переопределить var
с val
помощью .
Ответ №2:
Во-первых, причина, по которой вы можете переопределить val с помощью var, заключается в том, что это эквивалентно добавлению сеттера, в то время как в суперклассе был только геттер. И это довольно важно при реализации некоторых шаблонов.
Во-вторых, если вы открываете переменную, это означает, что вы хотите сделать ее изменяемой в подклассе. Не забывайте, что val означает «только для чтения«, а не «неизменяемый». И если вы хотите сохранить конфиденциальность сеттера, вы все равно сможете это сделать, когда переопределите
override var a = 1
private set
Ответ №3:
Потому что клиентские классы будут пытаться взаимодействовать с Main, как если бы это был тест. В этом смысл открытия теста, чтобы клиенты взаимодействовали с его дочерними элементами в расчете на то, что эти дочерние элементы будут вести себя как Тест и принимать все одинаковые вызовы методов и переназначения переменных.
Если Test заключает контракт со всеми своими пользователями-клиентами, которым разрешено изменять a, то Main нарушает этот контракт, если он делает a неизменяемым.
Комментарии:
1. Извините, что означает
client
ваш ответ?2. Это просто причудливые разговоры для любого класса, в котором есть объекты, которые в конечном итоге используют Test (или main). Люди часто используют термин «клиент» для класса, который что-то использует, и «сервис» для класса, который используется. Поэтому, если класс под названием User в какой-то момент использует Test, то другой разработчик в другой момент времени может решить вместо этого использовать Main, потому что он знает, что может. Но этот разработчик (который не является вами и не знает) обнаружил бы, что они не могли бы использовать Main, если бы он не вел себя как тест. Вот в чем причина ограничения.