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

wisconsin 18.09.2012 18:44

Объясните динамическое связывание и полиморфизм
 
пожалуйста помогите по этой теме, на простых примерах

bav 18.09.2012 18:57

Динамическое связывание, полиморфизм. Что не понятно?

wisconsin 18.09.2012 19:13

Цитата:

Сообщение от bav (Сообщение 1096396)

там нет примеров связанных с as

silin 18.09.2012 19:32

в теориях не силен, сори, если что
но мне представляется совсем простая штука:
с полиморфизмом понятно - наследники могут могут иметь свою реализацию свойств\методов базового класса,
а динамическим в этом контексте связывание будет потому, что на этапе компиляции не обязательно должно быть известно какая именно из реализаций понадобится
вот пример как бы из букваря, типов фигур может быть сколько захочешь, можно и других добавить - код не изменится
Код AS3:

package
{
 
        public class Main extends Sprite
        {
 
                public function Main():void
                {
                        var list:Vector.<Figure> = Vector.<Figure>([new Circle(), new Square()]);
 
                        for each(var fig:Figure in list)
                        {
                                // компилятор здесь не знает какие наследники Figure в списке
                                // все это выяснится в рантайме
                                trace( "fig : " + fig +"; area : " + fig.area());
                        }
 
                }
 
        }
 
}
 
class Figure
{
        public var size:Number = 1;
        public function area():Number {        return 0;}
}
 
class Circle extends Figure
{
        override public function area():Number        { return 0.25 * Math.PI * size * size;        }
}
 
class Square extends Figure
{
        override public function area():Number        { return  size * size;        }
}


wisconsin 18.09.2012 20:12

Цитата:

Сообщение от bav (Сообщение 1096396)

первая ссылка вообще не к теме...


silin, я не разобрался с примером, просто я не все изучил и есть в этом примере вещи мне непонятные

может есть какая-нибудь метафора для объяснения полиморфизма и динам связ

artcraft 18.09.2012 20:52

полиморфизм это когда пудель одновременно является собакой, зверем, живым существом и домашним животным, но для некоторых он просто Шарик

под динамическим связыванием вы вероятно имели в виду Data binding
метафора: кукла вуду связана с жертвой, если куклу колоть иголками, то это мгновенно отразится на жертве
(свойство "полученный урон" жертвы связано с аналогичным свойством куклы)

dimarik 18.09.2012 21:05

Цитата:

пудель одновременно является собакой
А если переопределить его методы "гав" и "апорт", то он сможет быть и танком. Вот такая тут метафора, вот такая полиморфизма.

Krusty 18.09.2012 21:12

Цитата:

Сообщение от dimarik (Сообщение 1096433)
А если переопределить его методы "гав" и "апорт", то он сможет быть и танком. Вот такая тут метафора, вот такая полиморфизма.

Только вот делать такого нельзя, так как это нарушает базовый принцип ООП. Если метод есть у родителя, то должен быть и у потомка, и делать то же самое. Детали реализации внутри могут быть разные, конечно, но результат должен быть одинаков. Поэтому танк и собака не могут быть в одной цепочке наследования(ну кроме базовой "объект реального мира"), так как либо собака будет стрелять, либо танк гавкать.

artcraft 18.09.2012 21:37

полиморфизм это не наследование
хоть и тесно связаны

полиморфизм это когда к одной конкретной собаке в зависимости от контекста можно обращаться по разному, эй пудель, или эй шарик, или эй кучерявый и в любой ситуации это будет верно т.к. эта конкретная собака является кучерявым пуделем шариком

наследование это когда пудель расширяет более общее понятие собака, которое в свою очередь расширяет еще более общее понятие зверь

silin 18.09.2012 21:45

Цитата:

Сообщение от wisconsin (Сообщение 1096421)
я не разобрался с примером, просто я не все изучил и есть в этом примере вещи мне непонятные

может есть какая-нибудь метафора для объяснения полиморфизма и динам связ

с метафорами еще хуже, чем с теорией :)
геометрическая фигура (Figure) может быть всякой, что и описываем в наследниках (Circle и Square)
в моем примере это вычисление площади, в базовом классе пустышка (необязательно, но здесь так уж вышло), для круга и квадрата своя конкретика, реализация area() для каждого своя - полиморфизм

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

var circle:Circle = new Circle();
var circleArea:Number = circle.area();

компилятор заведомо знает метод какого класса вызывается - статическое связывание

2)работаем с любой фигурой
вычисляем, например объем 3d-плюшки, выдавленной из фигуры
Код AS3:

function calcVolume(fig:Figure, height:Number):Number
{
        return height * fig.area();
}

компилятор не знает, какая фигура (экземпляр какого класса) будет передана в метод, но сработает fig.area(), соответствующий именно типу (классу) этого экземпляра - динамическое связывание

Krusty 18.09.2012 22:21

Цитата:

Сообщение от artcraft (Сообщение 1096445)
полиморфизм это не наследование
хоть и тесно связаны

полиморфизм это когда к одной конкретной собаке в зависимости от контекста можно обращаться по разному, эй пудель, или эй шарик, или эй кучерявый и в любой ситуации это будет верно т.к. эта конкретная собака является кучерявым пуделем шариком

наследование это когда пудель расширяет более общее понятие собака, которое в свою очередь расширяет еще более общее понятие зверь

Если писать про полиморфизм в терминах собак, то выходит немного не так.
В данном случае полиморфизм-это "интерфейс" i_Жрать_Спать_Гадить, который реализуют класс Собака и класс Кошка. Соответственно, нам известно, что шарик(экземпляр класса Собака), может быть накормлен, так как реализует этот интерфейс i_Жрать_Спать_Гадить. Причем неважно, это шарик или мурка(экземпляр класса Кошка)- в обоих случаях он может быть накормлен. То есть вообще неважно, к какому классу принадлежит объект-главное наличие реализации i_Жрать_Спать_Гадить

artcraft 18.09.2012 22:43

ну я не стал про интерфейсы писать, там у автора поста похоже и так не успевает укладываться всё голове.

приведение объекта типа пудель к типу животное это полиморфизм, я всё верно написал

выгода в том что пуделя можно записать в один список с кошкой муркой и диким крокодилом,
а потом в цикле обращаться с ними как со зверями - кормить и гладить

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

strangedk 18.09.2012 22:55

Даже зная что такое полиморфизм, когда читаешь все объяснения - начинаешь путаться :)

Не находил еще толкового примера. Все объясняют на своих примерах, придуманных в своей голове и понятных зачастую только себе. Полиморфизм можно объяснить и на пальцах, только иногда очень важно видеть лицо человека и понимать, он уже запутался или еще нет.

wisconsin 18.09.2012 23:28

с динамическим и статическим связыванием разобрался

а полиморфизм это принцип, при котором подклассы имеющие общий суперкласс, содержат общие свойства и методы, а также перекрытые методы выполняющие одинаковую цель, но по разному... как-то так

главное, что я для себя понял, то что полиморфизм это принцип, а не средства языка, с помощью которых можно использовать этот принципы

artcraft 18.09.2012 23:40

полиморфизм это когда к классу можно обратиться как к суперклассу или как к интерфейсу

например
класс А имплементирует интерфейс IA
а класс В наследуется от класса А

так вот полиморфизм это то что можно сделать так
Код AS3:

var a:IA = new B();


wisconsin 18.09.2012 23:43

Цитата:

Сообщение от artcraft (Сообщение 1096445)

полиморфизм это когда к одной конкретной собаке в зависимости от контекста можно обращаться по разному, эй пудель, или эй шарик, или эй кучерявый и в любой ситуации это будет верно т.к. эта конкретная собака является кучерявым пуделем шариком

хм, и как это изобразить в виде иерархии классов

artcraft 19.09.2012 00:17

тут не только иерархия но и интерфейсы

Код:

сlass Пудель extends Cобака
сlass МояСобака extends Пудель implements IКучерявый, IШарик

var мойПёс:МояСобака = new МояСобака();
trace( мойПёс is Пудель ); //true
trace( мойПёс is Cобака); //true
trace( мойПёс is IКучерявый); //true
trace( мойПёс is IШарик); //true


dimarik 19.09.2012 15:21

Цитата:

Сообщение от Krusty (Сообщение 1096439)
Только вот делать такого нельзя, так как это нарушает базовый принцип ООП. Если метод есть у родителя, то должен быть и у потомка, и делать то же самое. Детали реализации внутри могут быть разные, конечно, но результат должен быть одинаков. Поэтому танк и собака не могут быть в одной цепочке наследования(ну кроме базовой "объект реального мира"), так как либо собака будет стрелять, либо танк гавкать.

Расскажите еще что-нибудь про то, что нельзя делать. Заодно раскройте суть фразы "делать то же самое". И где та грань, которая определяет "тоже самое" от "совершенно другое"? Я не страдаю тягой переносить в архитектуру аналогии из окружающего мира. Перефразирую. "Прапорщик сказал, что собака — танк, значит ищи пушку".

Krusty 19.09.2012 15:52

Я ваш сарказм не понимаю.

artcraft 19.09.2012 17:02

я целиком согласен с Krusty
ничего не мешает сделать из собаки танк, но делать этого не стоит
если вы хотите использовать повторно то общее что есть и в собаке и в танке, то следует вынести это общее в отдельный класс

strangedk 20.09.2012 00:48

А я согласен с dimarik, т.к. меня порой угнетают объяснения и приведения на реальных примерах.

При чем уже не первый раз наблюдаю, что всё начинается более-менее понятно, и вроде бы чтобы объяснить задающему вопрос - но дальше уже 5-6 взрослых кодеров уже сами начинают путаться о том что пишут, хотя в коде легко решили бы эту задачу.

Лучше никакой аналогии чем неудачная.

wvxvw 20.09.2012 02:02

Есть еще такой момент: о полиморфизме начинают вспоминать (как и о всем другом), когда его нет. А нужен он тогда, когда у вас появляется лес из if'ов. Т.е. когда у вас есть несколько функций внутри которых вы повторяете одно и то же условие - это значит, что вам нужно переделать код так, чтобы это не происходило. Разные языки этого добиваются по-разному, но в любом случае назовут это полиморфизмом.
В AS3 такой механизм обеспечивается через наследование, или интерфейсы. Это помогает выделить отдельные части кода связанные логически в соответствующие им сущности (классы), а другой части кода оставаться универсальной по отношению к ним работать "по контракту" полученному либо от интерфейса, либо из описания класса, что и есть, практически, одно и то же.

Пример:

Код AS3:

function feed(animal:Animal):void
{
    if (animal.kind == Animal.DOG)
    {
        animal.eat(new DogFood());
    }
    else if (animal.kind == Animal.CAT)
    {
        animal.eat(new CatFood());
    }
    else
    {
        //...
    }
}
 
function strikeAndListen(animal:Animal):String
{
    var animalSays:String;
    if (animal.kind == Animal.DOG)
    {
        animalSays = "bark";
    }
    else if (animal.kind == Animal.CAT)
    {
        animalSays = "purr";
    }
    else
    {
        //...
    }
    return animalSays;
}

Напрашивается сделать так:

Код AS3:

class Dog extends Animal
{
    public function feed():void { ... }
 
    public function strikeAndListen():String { ... }
}
 
class Cat extends Animal
{
    public function feed():void { ... }
 
    public function strikeAndListen():String { ... }
}

Последний пример использует полиморфизм. Т.как у нас появилось несколько функций с одинаковым названием и одинаковым поведением, но в разных классах (поли - значит "много", "морфизм" - математический термин, который проще продемонстрировать на свойстве геометрических фигур быть "одинаковыми", если к ним были приложены трансформации переноса, поворота, отражения, или их комбинации. Но в более широком смысле, это свойство сохранения структуры между различными носителями этой структуры.)
Полиморфизм, в этом контексте, это неформальный антоним мономорфизма, т.как мономорфизм обязывает, что если f(g(x)) = f(y(x)), то g = y. Т.е., неформально, для существования морфизма обязательным условием является тот факт, что если функции ведут себя одинаково, то это одна и та же функция. Соответственно, в полиморфизме, допускается, что при f(g(x)) = f(y(x)), g != y (что мы и видим в примере с кошкой и собакой - у нас есть две функции, которые ведут себя одинаково, но не равны).

artcraft 20.09.2012 02:04

топикстартер попросил метафору,
все люди разные, некоторым нагляднее код, некоторым примеры из реальной жизни

если вы находите мою метафору неудачной - предложите более удачную, или попробуйте объяснить лучше чем это сделал я :)

in4core 20.09.2012 02:45

Уважаемый wvxvw *( и остальные если есть дельный совет), это вы очень интересно сказали о полиморфизме как сокращении if ов (однотипных действий).

А что вы скажите о такой задачке :
Предисловие :
Пишу сайт , имеем wrapper для секций. В каждой секции от тех или иных условий , может появится скролл ВСЕГО контента ( находится всегда на одной и той же координате по х )
Чтобы скролл работал ему нужно передать параметры контента, маски, высоты прокрутки и т.п.
А вот теперь задача :

Если создавать скролл внутри каждой секции ( позиционировать, рисовать и т.п.) , то передать в него параметры и настроить как нужно не составит труда. НО не глупо ли писать однотипный код по рисованию и позиционированию скроллам в каждой секции, когда можно ведь добавить скролл во wrapper ?
На первый взгляд, лучше добавить во wrapper...

Код AS3:

in wrapper ( this.addEventListener(SectionEvent.CHECK_SCROLL , onCheck)  )
in Section  ( this.dispatchEvent(new SectionEvent(SectionEvent.CHECK_SCROLL , this._content , this._mask , this_way ) )

Так вот, что с одной стороны некрасиво, что с другой . ( пугает именно большая передача, казалось бы, не нужных врапперу данных)
Как бы делали вы ? Может есть альтернативные варианты :)

artcraft 20.09.2012 03:02

Не уверен что понял проблему, но попробую дать совет

как я понял у вас контейнер управляет параметрами контента.
я предлагаю вам создать интерфейс для объектов которые можно вставлять в контейнер
и контейнер будет управлять контентом используя этот нитефейрс
а контент будет этот интерфейс реализовывать,
таким образом контейнер не будет знать как устроен контент, но сможет им управлять

для скроллинга контента контейнеру нужно будет уметь узнать высоту контента и иметь возможность изменять вертикальную позицию

wvxvw 20.09.2012 03:28

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

in4core 20.09.2012 13:12

Скроллер может быть только один, поэтому конечно писать лучше во вреппере. wvxvw - про было бы идеально не понял немного о какой ситуации идет речь.

У меня приблизительно щас так :

Код AS3:

public class ContentWrapper extends Sprite implements IDestroyable
 
public function init(sectionData:XMLList)
{
  ....
}
public function openContent(sectionID:int):void
{
    switch(sectionID)
    case 0this._section = new PortfolioSection();
    break;
    case 1this._section = new ContactSection();
    break; ....
 
    this.addchild(this._section);
    this._section.init( sectionData["section_" + sectionID] );
    this._section.addEventListener(WrapperEvent.CHECK_SCROLL , onCheck);
}
 
private function onCheck(e:WrapperEvent):void
{
    if(e.param == "scroll.hide")  this._scroll.destroy();
    else
    {
        this._scroll.define( e.param[1] , e.param[2] ... )
    }
 
}



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

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