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

SorrowN00b 14.08.2009 14:11

Как правильней проверить соответствие типа
 
Я хочу, чтобы некий класс A реализовывал интерфейс I и был Sprite.
У А будет много подклассов А1 А2 А3 (список расширяется), реализующих функции из I, при этом есть класс-манагер M, который эти A1 A2 ... создает в изобилии по требованию. Хотелось бы сделать поизящнее.
Первое что напрашивается:
- написать интерфейс I
- A extends Sprite implements I
- А1 extends A, А2 extends A, А3 extends A etc
- манагер M имеет переменную типа A и создает одного из A1-A2-A3 в зависимости от вызова и рулит какое-то время
Что не нравится: придется в A прописать пустые функци из I и в A1, A2, A3 постоянно override их, как-то не лежит душа. И вообще в этой схеме непонятно зачем нужен I, можно сразу прописать функции в A и override-ть их в А1 А2 А3, А в таком случае выполняет функцию абстрактного класса, для чего в AS3 интерфейсы и есть.

Если не писать интерфейс I и A, а напрямую делать A1 A2 A3, то это вообще паршиво - если программер делающий A4 A5 пропустит нужные функции, будет плохо.

Если не делать A, а напрямую реализовывать I в А1 А2 А3
А1 extends Sprite implements I
А2 extends Sprite implements I
то не совсем понятно, как проверить в M соответствие типа, если переменная для экземпляра будет типа Sprite, то нет гарантии, что в A5 реализовали I, если же переменная будет типа I, то для оперирования с этой переменной как со Sprite придется постоянно приводить тип, что тоже неизяЩно

Как бы тут поступить поООПшней?

wvxvw 14.08.2009 14:53

Код AS3:

if ((A1 is I) && (A1 is Sprite)) { .... }


SorrowN00b 14.08.2009 15:03

Это понятно, это контроль при создании и throw error, мне просто лениво постоянно делать override и приводить тип
Код AS3:

(A1 as Sprite).x = 200

Вот я и ищу более кузявый путь, чтобы "сразу и само". Если вариантов нет, буду так как выше делать.

iflamberg 14.08.2009 15:18

вы об этом что ли?
Код:

var interfaceInstance:I = A1 as I;
interfaceInstance.x=200;


SorrowN00b 14.08.2009 15:57

Вово, тыща временных foo
Код AS3:

var foo:I = A1 as Sprite;

И вечные override method1, override method2 в A1 A2 не нравятся.
И контроля типа на уровне компиляции нет.
И интерфейс I в таком случае просто не нужен ни в каком разрезе.
Вот есть способ сделать сразу и все? Если нет, я смирюсь ;)

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

dimarik 15.08.2009 11:09

Цитата:

Сообщение от SorrowN00b (Сообщение 842727)
Как бы тут поступить поООПшней?


Вариант первый: Вам придется оверрайдить методы в подклассах, расширяющих A и не использовать интерфейс I вовсе. Следить за тем, чтобы методы были заоверрайдены придется вручную. На этапе компиляции это не удастся отследить. Инстансы A1, A2...AN будут иметь тип A.

A extends Sprite
А1 extends A
А2 extends A
А3 extends A
Код:

class A extends Sprite {
        public virtual function doSomething():void {
                throw new IllegalOperationError('Method must be overrided by subclass');
        }
}

А1 extends A {
        public override function doSomething():void {
                trace('Hello, I am А1');
        }
}

А2 extends A {
        public override function doSomething():void {
                trace('Hello, I am А2');
        }
}

class M {

    public function M() {
        this.doJob();
    }

    public function doJob():void {
        var className:String = 'A' + int(Math.random() * 2) + 1;
        var c:Class = getDefinitionByName(className) as Class;
                    var instance:A = new c() as A;
        instance.x = 100;
        instance.doSomethimg();
    }
}

Второй вариант: имплементить интерфейс I во всех классах (A1, A2, A3) и работать с типом интерфейса.

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

Для этого варианта в I должны быть описаны _все_ геттеры/сеттеры и методы, через которые предполагается работать с экземпляром.

Опишите в I все проперти и методы Sprite с которыми собираетесь работать, а также методы и проперти, реализуемые во всех A1, A2...AN. Для code reusing полезно отекстендить I от ISprite.

А1 extends Sprite implements I
А2 extends Sprite implements I
А3 extends Sprite implements I

Код:

А1 extends Sprite implements I {
        public function doSomething():void {
                trace('Hello, I am А1');
        }
}

А2 extends Sprite implements I {
        public function doSomething():void {
                trace('Hello, I am А2');
        }
}

public interface ISprite {
        // DisplayObject implementation
  function set x(value:Number):void;
  function get x():Number;
}

public interface I extends ISprite {
  function doSomething():void;
}


class M {

    public function M() {
        this._factory = new AFactory();
        this.doJob();
    }

    private var _factory:  IIFactory;

    public function doJob():void {
        var className:String = 'A' + int(Math.random() * 2) + 1;
        var instance:I = this._factory.newInstance(className);
        if (instance != null) {
                instance.x = 100;
                instance.doSomethimg();
        }
    }
}

internal class AFactory implements IIFactory {
                public function newInstance(className:String):I {
        try {
                                    var c:Class = getDefinitionByName(className) as Class;
                                    var instance:I = new c() as I;
                                    return instance;
                                } catch (e:TypeError) {
                                    return null;
                                }
                }
}

Код:

public interface IIFactory {
  function newInstance(className:String):I;
}


SorrowN00b 17.08.2009 16:44

Ну, это все понятно, не стоило утруждаться так все подробно расписывать, спасибо за ваше время :)
Во втором варианте, конечно, напрягает следующее:
Цитата:

Опишите в I все проперти и методы Sprite с которыми собираетесь работать
Короче, я в пролете, будем оверрайдить.


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

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