Форум 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=215556)

djken 15.05.2018 01:26

Как правильно расширить класс?
 
Привет всем.
Подскажите пожалуйста как сделать правильно.
Есть класс ImageBox - некий контейнер, которому можно задавать размеры, в себя умеет загружать картинку и пустое место заполнять выбранным фоном.

От этого класса будут производные классы. Например, класс ImageBoxExt - делает все тоже самое что и ImageBox, но еще при наведении должны внутри появляться кнопка корзины и чекбокс.

http://www.flasher.ru/forum/attachme...chmentid=33228


Наследоваться от ImageBox?
Код AS3:

public class ImageBoxExt extends ImageBox

Проблема: в конструкторе после super добавляю кнопку корзины и чекбокс. Но после того как загружается основная картинка, она закрывает все новосозданные кнопки ) Следовательно, в этом классе нужно перекрывать родительские методы - а это неправильно.

Либо просто создавать класс, наследуясь от Sprite и внутри создавать экземпляр класса ImageBox?
Код AS3:

public class ImageBoxExt extends Sprite
{
  private var _ib:ImageBox;
...
  _ib = new ImageBox(...);
  addChild(_ib);
  // и тут добавлять новые кнопки
...
}


undefined 15.05.2018 02:58

Цитата:

Следовательно, в этом классе нужно перекрывать родительские методы - а это неправильно.
Почему?

djken 15.05.2018 08:38

Undefined, почему нужно перекрывать? Или почему это неправильно?

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

А неправильно, т.к. это нарушение инкапсуляции..

caseyryan 15.05.2018 10:06

Цитата:

Следовательно, в этом классе нужно перекрывать родительские методы - а это неправильно.
Неправильно? Это один из принципов ООП, так сказать, один из трёх китов)
Цитата:

А неправильно, т.к. это нарушение инкапсуляции..
Нет, это неправильная архитектура изначально.

Если изначально планируется, что в базовом классе грузится какая-то картинка, а объекты дочерних классов должны знать об этом, то и архитектуру родительского класса надо делать сразу с учетом этого.
Если нужно дождаться загрузки картинки, то можно обработчику сделать модификатор protected и в дочернем классе просто его перезаписать
Код AS3:

// в базовом классе
protected function onImageLoaded(e:Event):void {
      ... добавляется картинка
}
// в наследнике
override protected function onImageLoaded(e:Event):void {
    super.onImageLoaded(e);
    .. тут добавляешь свои чекбоксы
}

Я бы вообще добавление чекбоксов вынес из конструктора в отдельный метод, и просто вызывал его после загрузки картинки
Код AS3:

override protected function onImageLoaded(e:Event):void {
    super.onImageLoaded(e);
    addCheckboxesAndOtherCrap();
}

как-то так

djken 15.05.2018 13:55

caseyryan, спасибо большое!
Для личного пользования всегда обходился только private и public. Но в данном случае не хотелось использовать public у родительского метода для перезаписи в наследнике, т.к. onImageLoaded не относится к интерфейсу данного класса.

Теперь буду знать про protected )

Цитата:

то и архитектуру родительского класса надо делать сразу с учетом этого
Но все же - какая в данном случае архитектура была бы правильная? Или имелось ввиду использование protected?

caseyryan 15.05.2018 14:19

Цитата:

Но все же - какая в данном случае архитектура была бы правильная? Или имелось ввиду использование protected?
Правильно в данном случае - иметь возможность уведомить наследников о загрузке картинки.
Цитата:

Теперь буду знать про protected )
protected это всего лишь один из 4 штатных модификаторов доступа, означает доступ для наследников. Есть еще internal для свойств доступных внутри пакета. Можно и свое пространство имен объявить, но тут это избыточно

djken 15.05.2018 14:37

А, ну у меня в родительском методе вконце стоит диспатч события после загрузки картинки.
Код AS3:

dispatchEvent(new Event('COMPLETE'));

Получается я могу его так же в наследнике слушать.. я что-то не додумался сразу до этого )
Код AS3:

super.addEventListener('COMPLETE', onCompleteHandler);
...
 
private function onComplete(e:Event):void
{
        var _cb:CheckBox = new CheckBox();
        addChild(_cb);
}

Значит можно без override обойтись )
Пасиб! )

GBee 15.05.2018 14:47

Так может картинку на 0 уровень всегда пихать после загрузки?

undefined 15.05.2018 17:26

Цитата:

Значит можно без override обойтись
Тебе явно кто-то вбил в голову,что override - это плохо.Это не так.

caseyryan 15.05.2018 17:28

Цитата:

Сообщение от djken (Сообщение 1205242)
А, ну у меня в родительском методе вконце стоит диспатч события после загрузки картинки.
Код AS3:

dispatchEvent(new Event('COMPLETE'));

Получается я могу его так же в наследнике слушать.. я что-то не додумался сразу до этого )
Код AS3:

super.addEventListener('COMPLETE', onCompleteHandler);
...
 
private function onComplete(e:Event):void
{
        var _cb:CheckBox = new CheckBox();
        addChild(_cb);
}

Значит можно без override обойтись )
Пасиб! )

Ну, во-первых писать типы событий хардкодом типа "COMPLETE" - это моветон. Можно легко опечататься и потом думать и гадать, почему не работает. Всегда используй для этого константы.
Во-вторых, для события complete есть штатная константа Event.COMPLETE, даже свою объявлять не надо
Ну и в третьих - отправка события - это всегда более ресурсоемкий способ, чем вызов метода. У тетя там и так событие приходит при загрузке картинки. Создавать еще одно - это оверхэд. Оверрайд в данном случае более правильный подход. Не нужно ни слушателей дополнительных ни событий и всё по ООПшному
А если событие все-таки нужно для чего-то ещё, то ты можешь не создавать новое, а просто передиспатчить то же
Код AS3:

dispatchEvent(e);



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

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