Вот век живи, век учись.
Оказывается в большинстве ООП языков (Java, C#, TypeScript) нет возможности присвоения пропертей до вызова конструтора суперкласса, а вызов виртуального метода из конструтора — плохая практика.
Рассмотрим следующий код:
class AButton {
constructor() {
this.fill();
}
protected fill() {
// предполагается, что он строит кнопку на основе getColor()
// вообще, код этого метода мог бы вполне содержаться и в конструкторе
}
protected abstract getColor(): string;
}
class ButtonWithCustomColor extends AButton {
protected color: string;
constructor(color: string) {
this.color = color; // Получаем ошибку здесь - доступа к свойствам ещё нет
super();
}
protected getColor() { return this.color; }
}
Не выходит аленький цветочек.
Придётся каждый раз вызывать не только конструктор, но и метод fill() извне (а из конструктора его выбросим), чем полностью убиваем смысл сокрытия кишок внутри объекта.
Было:
btn = new Button();
Стало:
btn = new Button();
btn.fill(); // не дай вам бог забыть это вызвать
btn.fillSomethingElse(); // а у нас наверняка и другие кишочки выпрут наружу рано или поздно
Что самое интересное, так это то, что ничего по сути не меняется, кроме нотации.
Ничто не мешает компилятору давать доступ хотя бы к пропертям объекта до вызова конструктора суперкласса.
Кто-нибудь может мне пояснить, какая же best practice для подобных случаев? И почему простое логичное решение заменено плохим нелогичным?