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

Appleman 13.12.2017 14:47

Интерфейс и его имплементация
 
Вопрос по книге Сандерса о паттернах проектирования в AS3 (Купил вчера в PDF в прекрасном качестве, весь код можно копипастить, если кому надо книжку, с радостью поделюсь). Авторы пишут о предпочтении "программирования от интерфейса (супертипа), а не его имплементации". В качестве примера приводится то, что в моей программе выглядело бы вот так:

Код AS3:

private var hero:Character = new Hero();

разумеется, Hero - наследник Character. Я правильно понимаю, что при таком объявлении во-первых, не будет ошибки компиляции, во-вторых, везде, где параметр типизируется как Character, мой передаваемый туда hero также пройдёт без ошибок, и в-третьих, если где-то будет обращение к свойству другого наследника Character (например Enemy), я сразу получу ошибку в рантайме?

И что вообще уважаемые знатоки думают о таком подходе?

undefined 13.12.2017 14:58

ты сразу ограничиваешь функционал своего героя суперклассом Character, теряя всю специфику Hero

illuzor 13.12.2017 15:03

Цитата:

И что вообще уважаемые знатоки думают о таком подходе?
Такой "подход" называется полиморфизмом - это один из принципов ООП. Изучите сначала его, чтобы не задавать подобные странные вопросы.

Appleman 13.12.2017 16:10

Цитата:

Сообщение от illuzor (Сообщение 1203397)
Такой "подход" называется полиморфизмом - это один из принципов ООП. Изучите сначала его, чтобы не задавать подобные странные вопросы.

Вообще-то я привёл ход рассуждения. Тот полиморфизм, который я знаю (хотя безусловно не претендую на экспертность ни в какой степени, поэтому и спрашиваю), вполне будет "работать" и в такой форме:

Код AS3:

public var hero: Hero = new Hero();

при условии, что Hero - наследник Character. Более того, если какой-то метод в Character будет записан как "абстрактный" и переопределён в классе-наследнике Hero, то в соответствии с принципом полиморфизма он будет корректно вызван для экземпляра типа Hero, несмотря на то, что объявлен он не с использованием имени суперкласса. Собственно об этом и вопрос.

Wolsh 13.12.2017 19:54

Цитата:

если где-то будет обращение к свойству другого наследника Character (например Enemy), я сразу получу ошибку в рантайме?
Ты получишь ошибку компиляции при обращении к свойству Enemy или Hero, без разницы.

Ты объявил переменную как Character. Абсолютно неважно, что ты туда запихаешь в рантайме. Компилятор видит, что ты пытаешься вызвать несуществующий метод именно у Character. Это тип переменной, и он не зависит от того, какой конкретно объект туда записан.

Appleman 13.12.2017 21:33

Цитата:

Сообщение от Wolsh (Сообщение 1203447)
Это тип переменной, и он не зависит от того, какой конкретно объект туда записан.

На фига тогда так писать? Или предполагается, что суперкласс полностью абстрактный и не содержит ВООБЩЕ никакой реализации, оставляя всё своим наследникам?

undefined 13.12.2017 21:43

часто так пишут в сигнатурах методов, а не при объявлении переменных.
Код AS3:

public function doSomething(character:Character):void


Wolsh 13.12.2017 21:44

Я не понимаю этого вопроса.
Ну вот у тебя допустим объявлена переменная типа Спрайт.
Ты можешь туда любую кнопку запихать.
Но если ты в коде обратишься к этой переменной не как к Спрайту, а как к кнопке, то получишь ошибку компиляции? Конечно получишь, потому что у Спрайта нет таких свойств которые ты добавил в кнопку-наследника. Для компилятора это Спрайт! Потому что переменная имеет тип Спрайт. И компилятору не надо дожидаться рантайма чтобы указать тебе на ошибку: ты вызываешь свойства и методы, которых нет у данного типа. Если хочешь обращаться к свойствам и методам кнопки, укажи что это кнопка и проблем не будет. Что тут нелогичного?

Appleman 13.12.2017 22:02

Как будто это я придумал :)
Вот смотрите из книги по шаблонам проектирования, буквально первая глава:
Код AS3:

// Абстрактный класс
public class Polymorphism
{
public function myMusic():void
{
// Резервные детали для подклассов
}
}
 
public class Rock extends Polymorphism
{
override public function myMusic():void
{
trace(“Play Jimmie”);
}
}
 
import flash.display.Sprite;
public class PlayMusic extends Sprite
{
var rock:Polymorphism;
var classic:Polymorphism;
var country:Polymorphism;
var jazz:Polymorphism;
public function PlayMusic():void
{
rock=new Rock();
rock.myMusic();

Вот видите, как в самом конце всё собирается вместе?

Wolsh 13.12.2017 22:44

И? Класс Rock же не создал новый метод, которого нет в Polymorphism. Он переопределил суперметод. В этом и заключается полиморфизм. А вопрос то в чем?)

Переменная rock имеет тип Polymorphism.
У типа Polymorphism есть метод myMusic().
У переменной rock вызывается метод myMusic(), который есть у ее типа.
Где тут компилятору кричать "Караул!"?


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

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