Почему мы должны избегать использования открытых членов базового класса? - PullRequest
0 голосов
/ 09 февраля 2019

Пока я читал документ о Котлине, я увидел, что нам следует избегать использования open свойств, объявленных в базовом классе:

Это означает, что к моментувыполнение конструктора базового класса, свойства, объявленные или переопределенные в производном классе, еще не инициализированы.Если какое-либо из этих свойств используется в логике инициализации базового класса (прямо или косвенно, через другую переопределенную реализацию открытого члена), это может привести к некорректному поведению или сбою во время выполнения.Поэтому при разработке базового класса следует избегать использования открытых членов в конструкторах, инициализаторах свойств и блоках инициализации.

В документе сказано, что свойства в производном классе еще не инициализированы, когда конструктор базового классаназывается.Но как мы можем получить доступ к свойствам производного класса, которые не инициализированы, из конструктора базового класса (я предположил, что incorrect behavior or a runtime failure было вызвано этой ситуацией)?Возможно ли это?

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

Открытые функции в Kotlin - это функции, которые могут быть переопределены подклассом.Как правило, рекомендуется ограничивать наследование класса, поскольку вы должны предоставить классу необходимые коды, чтобы сделать его перезаписываемым.Если вы не хотите, чтобы класс переопределил ваш базовый класс, тогда вы должны сделать его окончательным.Таким образом, Kotlin сделает это легко, сделав каждый класс и метод финальным по умолчанию.Вы можете найти более подробный ответ в главе «Объекты и класс» книги «Котлин в действии».

Так называемая проблема хрупкого базового класса возникает, когда модификации базового класса могут вызвать некорректное поведение подклассов.потому что измененный код базового класса больше не соответствует предположениям в его подклассах.Если класс не предоставляет точных правил того, как он должен быть разделен на подклассы (какие методы должны быть переопределены и как), клиенты рискуют переопределить методы так, как не ожидал автор базового класса.Поскольку невозможно проанализировать все подклассы, базовый класс является «хрупким» в том смысле, что любое его изменение может привести к неожиданным изменениям поведения в подклассах.Чтобы защитить от этой проблемы, «Эффективная Java» Джошуа Блоха (Addison-Wesley, 2008), одна из самых известных книг о хорошем стиле программирования Java, рекомендует вам «разрабатывать и документировать для наследования или иным образом запретить его».Это означает, что все классы и методы, которые специально не предназначены для переопределения в подклассах, должны быть явно помечены как окончательные.Котлин следует той же философии.В то время как классы и методы Java открыты по умолчанию, Kotlin по умолчанию является окончательным.

0 голосов
/ 09 февраля 2019

Я не знаю kotlin, но я предполагаю, что open совпадает с virtual в других языках.Небезопасно вызывать виртуальные члены в конструкторе базового класса, потому что базовый конструктор вызывается перед производным конструктором.Если переопределенное свойство требует полной инициализации производного класса, это может вызвать ошибки, поскольку производный конструктор еще не был вызван, когда вы находитесь внутри базового конструктора.По крайней мере, так работает в языках .NET, таких как C #.

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