Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Наследование реализации (http://www.flasher.ru/forum/showthread.php?t=133044)

SamFR 26.11.2009 01:15

Наследование реализации
 
Здравствуйте.

Давно уже мучаюсь следующим вопросом. AS3 поддерживает только наследование типа, между тем в некоторых случаях очень хорошо было бы применить наследование реализации. В этом, в принципе, и состоит вопрос :)

Возмём следующий пример. Пусть имеется базовый класс ItemList, в интерфейс которого входят методы addItem() и deleteItem(). Это – визуальный класс списка, основанный на работе с единичными элементами. Также имеется производный от ItemList класс ListView, который определяет интерфейсный метод setDataProvider(). Этот производный список рассчитан на работу с поставщиком данных, однако в своей внутренней логике использует унаследованные методы addItem() и deleteItem().

Проблема состоит в том, что оставлять эти методы открытыми нехорошо по той причине, что производный класс уже не рассчитан на их прямое использование. В C++ я применил бы закрытое либо защищённое наследование (т.е. наследование реализации), или же композицию.

Композиция – вещь замечательная, более того, она применима и в AS. Но её не всегда удобно использовать. Например в случае того же ListView придётся добавлять используемый ItemList в качестве ребёнка.

Второе решение – определить базовый класс (назовём его CoreItemList), в котором будет содержаться реализация всех интерфейсных, по сути, методов, но они будут объявлены как защищённые. А от него уже наследовать ItemList, объявив в нём публичные обёртки для интерфейсных методов, а также ItemView, используя унаследованные методы в качестве защищённых. Несмотря на свою простоту, это решение кажется мне немного кривоватым :)

Был бы очень рад услышать ваши мысли, касающиеся данного вопроса)

wvxvw 26.11.2009 01:23

Это называется over-engineered :) Ну, смотрите, если другой програмист возьмет и переопределит ваш метод и не реализует его как нужно - то кто ему виноват, а зачем было лезть, если не знаешь куда? :)
Ну или если совсем не хотите чтобы метод переопределяли - есть final.
ИМО в виду того, что АС медленный делать всякие "обертки" и остальные красивости - чревато тормозами, и просто того не стоит.

SamFR 26.11.2009 01:37

Естественно, в некорректной реализации переопределённого метода будт виноваты только кривые руки программиста :) Нет, я не про переопределение.

Я про то, чтобы ограничить унаследованный интерфейс в случае, если производный класс не рассчитан на его прямое использование. Например, вызов ListView.removeItem() приведёт к тому, что будет удалён элемент списка, несмотря на то, что соответствующий элемент данных присутствует в поставщике. Это может привести к последующим ошибкам внутренней логики списка (например, когда от поставщика придёт сообщение об изменении сответствующего элемента данных).

Цитата:

Сообщение от wvxvw (Сообщение 868318)
ИМХО в виду того, что АС медленный делать всякие "обертки" и остальные красивости - чревато тормозами, и просто того не стоит.

Вот и я ж о том же)

etc 26.11.2009 07:47

Код AS3:

public override function addItem(...):void {
    throw new IllegalOperationError();
}
 
public override function removeItem(...):void {
    throw new IllegalOperationError();
}
 
...
 
private function update(...):void {
    ...
    super.addItem(...);
    ...
    super.removeItem(...);
    ...
}

Единственное что методы в родительском классе нужно делать вроде этого:

Код AS3:

public function addItem(...):void {
    this._addItem(...);
}

Т. е. реализация метода внутри _addItem и все вызовы в пределах класса идут через this._addItem, а не this.addItem.

switcher! 26.11.2009 12:30

Цитата:

Сообщение от etc (Сообщение 868341)
Единственное что методы в родительском классе нужно делать вроде этого

Код AS3:

public function addItem(...):void {
    this._addItem(...);
}


можно ли подробнее узнать зачем нужен метод-посредник? Для гибкости кода?
Ничего более путного, чем изменение количества аргументов в голову не приходит. А-ля:
Код AS3:

public function addItem(myVar:int):void {
    this._addItem(myVar);
    //или this._addItem(myVar, 1.5);
}
 
private function _addItem(myVar:int, anotherVar:Number = NaN):void {
    ...
}

опыта мало. увы...

+ ко всему прочему, это ситуация напомнила мне вызовы вроде:
dispatchEvent() -> dispatchEventFunction() -> метод-обработчик
с малопонятным вызовом метода-посредника. Хотя здесь можно списать на нативную реализацию, скрытую за 7-ю печатями.

etc 26.11.2009 14:30

Цитата:

Сообщение от switcher! (Сообщение 868374)
можно ли подробнее узнать зачем нужен метод-посредник?

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

switcher! 26.11.2009 14:53

да, точно. Кстати, очень своевременная информация. Спасибо!

SamFR 26.11.2009 16:36

etc, так я всегда, в принципе, и делал. А сейчас что-то вдруг захотелось узнать, нет ли более красивого решения :)
Мне в данном случае не очень нравится вызов дополнительного метода (хотя такое решение часто достаточно гармонично вписывается в логику класса). Но ещё хуже – набор интерфейсных методов, вызывающих безусловные ошибки. В документацию не все заглядывают, а автокомплит не дремлет :) Да и просто как-то это...

r_r_f_r 26.11.2009 16:48

Код:

[Deprecated(message="Поскольку-постольку", replacement="сюда-то", since="v 3.42.3.12.123.4.123.123")]

SamFR 26.11.2009 17:02

Ммм... Интересно, нужно будет попробовать. Но ведь он же только из доков и автокомплита исключает, правильно я понял? Хотя это уже лучше)

Добавлено через 3 минуты
Цитата:

Сообщение от r_r_f_r (Сообщение 868451)
"v 3.42.3.12.123.4.123.123"

Это с учётом количества изменённых печатных символов? Всегда хотел такую SVN :)


Часовой пояс GMT +4, время: 03:05.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.