Преобразование подкласса в родительскую переменную as3 - PullRequest
0 голосов
/ 07 января 2010

Я звоню на классы разных типов из цикла. Объекты могут быть разных типов, поэтому я использую метод getDefinitionByName. вот кусок моего кода:

for(var y = 0; y < mapH; y++)
            {
                brickHolder[y] = new Array();
                for(var x = 0; x < mapW; x++)
                {
                    var classRef = getDefinitionByName('com.objects.Brick2') as Class;
                    var brick:Brick2 = Brick2(new classRef());
                    brick.name = x+""+y;
                    brick.getBall(ball);
                    brick.getEngine(this);
                    brick.x = x * brick.bWidth + brick.bWidth;
                    brick.y = y * brick.bHeight + 100;
                    numberOfBricks += 1;
                    addChild(brick);

                }
            }

Единственная проблема в том, что я должен привести этот объект к определенной переменной:

var brick:Brick2 = Brick2(new classRef());

Я думал об использовании интерфейса и приведении его так:

var brick:IBrick = IBrick(new classRef());

Но я получил ошибку, когда попытался вызвать методы. Интерфейс пуст; нет никаких методов в этом. Я не уверен, если это имеет значение. Но родительский класс наследует его, а подклассы наследуют родительский класс. Могу ли я вместо этого использовать родительский класс?

var brick:ParentBrick2 = ParentBrick2(new classRef());

В двух словах, что я могу сделать, чтобы свободно привести эти объекты, чтобы я мог использовать любые методы подкласса, которые были вызваны?

Ответы [ 4 ]

0 голосов
/ 07 января 2010

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

0 голосов
/ 07 января 2010

[ОБНОВЛЕНИЕ] после копания кажется, что виртуальное ключевое слово игнорируется компилятором, поэтому это не сработает. Еще один недостаток AS3: (

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

http://msdn.microsoft.com/en-us/library/ms173152%28VS.80%29.aspx <- примеры C #, но хорошо объясняют идею. </p>

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

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

0 голосов
/ 07 января 2010

Да, вы определенно должны иметь возможность использовать родительский класс, например ::100100

var c:Car = new Mercedes();

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

Если я правильно помню свои странности AS3, проверка метода и имени члена выполняется во время выполнения, и вы должны иметь возможность вызывать любую функцию на Object. Таким образом, вы также можете привести все к Object:

var brick:Object = new classRef(); //or cast to Object
brick.name = x + "" + y;
brick.getBall(ball);

Но используйте родительский тип, как в примере с автомобилем. Это правильный полиморфизм.

0 голосов
/ 07 января 2010

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

Действительно плохой способ, который будет работать, - это вводить brick как «Object» или «*», что позволит вам вызывать любой метод, который вы захотите, и только даст вам ошибку во время выполнения вместо времени компиляции, если метод не существует Это плохой взлом, который вы должны избегать, если это возможно.

Вы также можете использовать методологию утки, когда вы вводите кирпич как «Объект», но вызываете методы, только если вы подтверждаете, что они действительно существуют.

var brick:Object = new classRef();
if ("getBall" in brick)
    brick.getBall();

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

...