25.11.2020, 01:20
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
ES6. Class constructor question
Здравствуйте.
У меня условно абстрактный класс для работы с сетью, от которого наследуется множество классов различных моделей, пример:
/**
* @abstract
*/
class AbstractHttpService {
baseRouteName;
constructor(baseRouteName) {
if (baseRouteName) {
this.baseRouteName = baseRouteName;
}
}
}
class ProductsHttpService extends AbstractHttpService {
baseRouteName = 'product';
}
Решил вкорячить кэширование экземпляров http-сервисов и тут понял, что из конструктора абстрактного класса никак не получить значение свойства "ребенка" до его инициализации.
Скажите, пожалуйста, есть ли какой-нибудь способ получить из абстрактного класса значение свойства класса, который наследуется от этого самого абстрактного класса?
Вижу только одно решение: вместо объявления для ребенка значения свойства по умолчанию передавать в конструктор родителя это самое значение.
|
|
25.11.2020, 08:24
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Сообщение от Nexus
|
Скажите, пожалуйста, есть ли какой-нибудь способ получить из абстрактного класса значение свойства класса, который наследуется от этого самого абстрактного класса?
|
Нет конечно. Это противоречит самим принципам ооп, классам, наследованию... Базовые классы никак не могут зависеть от своих потомков.
И то, что js глотает такую конструкцию - это скорее бага, чем фитча. Не должны переобъявляться поля базовых классов в наследниках.
Только так
class AbstractHttpService {
baseRouteName;
constructor(baseRouteName) {
this.baseRouteName = baseRouteName;
}
}
class ProductsHttpService extends AbstractHttpService {
constructor(baseRouteName) { super (baseRouteName)}
}
Последний раз редактировалось voraa, 25.11.2020 в 09:09.
|
|
25.11.2020, 15:18
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
Сообщение от voraa
|
И то, что js глотает такую конструкцию - это скорее бага, чем фитча.
|
В переопределении значения свойства базового класса не вижу ничего такого.
В каких языках переопределение свойства базового класса приведет к ошибке?
|
|
25.11.2020, 16:36
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Ну в C++ переобъявить просто не удастся. Будет поле в базом классе и поле с таким же именем в наследнике.
В js с методами так работает, а вот со свойствами нет. Свойство будет одно.
Вроде ошибки нет, но фигня может получиться. Если я беру чужой базовый класс, то придется скурпулезно изучить, какие у него поля, что бы случайно не написать такое же имя и работать с ним, как со своим.
Приватные свойства спасают. Там будет у базового класса свое, у наследника свое. Но из наследника к свойству базового не обратиться. protected в js еще не придумали.
Последний раз редактировалось voraa, 25.11.2020 в 17:13.
|
|
25.11.2020, 17:54
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
voraa, если и в других языках ошибки нет, значит в и js это все-таки не бага.
Сообщение от voraa
|
Если я беру чужой базовый класс, то придется скурпулезно изучить, какие у него поля, что бы случайно не написать такое же имя и работать с ним, как со своим.
Приватные свойства спасают. Там будет у базового класса свое, у наследника свое. Но из наследника к свойству базового не обратиться. protected в js еще не придумали.
|
Я не совсем нуб, чутка в программирование умею)
ps. в php базовый класс может работать со свойствами наследника прямо из конструктора и, имхо, это очень удобно, не нужно нагружать конструктор метода всяким мусором или каким-либо другим способом передавать классу его "настройки".
|
|
25.11.2020, 18:09
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Сообщение от Nexus
|
в php базовый класс может работать со свойствами наследника прямо из конструктора
|
Это как?
Но даже если знать, что у наследника должно быть поле с определенным именем, то в js сначала выполняется конструктор базового класса, а потом конструктор наследника. И при работе конструктора базового, полей наследника просто не существует.
|
|
25.11.2020, 20:10
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
Сообщение от voraa
|
Это как?
|
http://sandbox.onlinephpfunctions.co...f43864b2b53300
<?php
abstract class AbstractHttpService {
protected string $baseRouteName;
public function __construct(?string $baseRouteName = null) {
if ($baseRouteName) {
$this->baseRouteName = $baseRouteName;
}
var_dump($this->baseRouteName);
}
}
class ProductsHttpService extends AbstractHttpService {
protected string $baseRouteName = 'product';
}
new ProductsHttpService();// string(7) "product"
|
|
25.11.2020, 23:58
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Почти изящное решение
/**
* @abstract
*/
class AbstractHttpService {
baseRouteName;
constructor(baseRouteName) {
this.baseRouteName = baseRouteName ?? new.target.baseRouteName;
}
}
class ProductsHttpService extends AbstractHttpService {
static baseRouteName = 'product';
}
let x = new ProductsHttpService ()
console.log (x.baseRouteName)
|
|
26.11.2020, 00:37
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
voraa, я уже заменил переопределение свойства базового класса в наследуемом классе на передачу аргумента в конструктор.
Спасибо за пример решения, не знал, что у оператора new есть свойство target.
|
|
26.11.2020, 07:17
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Я даже не знаю, как назвать конструкцию new.target. В документациях это называется мета-свойство. Вроде как в Js у операторов не бывает свойств и ничего другого вида <оператор>.<свойство> не встречается. Просто данность такая.
|
|
|
|