#actionscript-3 #interface
#actionscript-3 #интерфейс
Вопрос:
Я создал интерфейс под названием iHero, который я реализую в своем классе hero.as3. класс hero написан так, чтобы его можно было наследовать в классе movieclip для обработки движения и т. Д. И т. Д. Но почему-то я не могу понять, как закодировать это с хорошей практикой.
Возможно, я в неправильном направлении.
Я хочу иметь подкласс movieclip, который будет, например, героем.
Должен ли я просто реализовать iHero в классе hero с помощью следующих методов, или это перебор? — Я думаю, я ищу ответ на то, что должно быть в интерфейсе, а что нет. Вот интерфейс.
package com.interfaces
{
public interface IHero
{
//movement
function MoveLeft():void;
function MoveRight():void;
function MoveUp():void;
function MoveDown():void;
//in battle
function DoDamage(isCasting:Boolean):void;
function DoHeal():void;
function Flee():void;
function TakeDamage():void;
function IsAlive():Boolean;
function CheckDeath():void;
function Die():void;
}
}
Комментарии:
1. Интерфейсы в as3 довольно часто излишни. Это не Java 🙂
Ответ №1:
Я думаю, что вы на правильном пути, независимо от того, правильный он или неправильный, всегда субъективно. Но если вы действительно хотите пойти по этому пути, я предлагаю вам прочитать эту статью Мика Уэста. Ему несколько лет, но он все еще очень применим.
Я думаю, что у вас действительно есть два разных интерфейса, но, вероятно, больше
public interface IMoveable {
function moveLeft(obj:DisplayObject):void;
function moveRight(obj:DisplayObject):void;
function moveUp(obj:DisplayObject):void;
function moveDown(obj:DisplayObject):void;
function Flee(obj:DisplayObject);
}
public interface IFightable {
function doDamage(withWeapon:IEquipableWeapon);
function takeDamage(fromWeapon:IEquipableWeapon);
function get isAlive():Boolean;
function checkDeath():void;
function Die():void;
function doHeal();
function get health():Number;
}
Затем….
public class SimpleMover implements IMoveable {
// The movement implementation
// for example:
public funciton moveLeft(obj:DisplayObject) {
obj.x = obj.x -= 10;
}
}
public class SimpleFighter implements IFightable {
// The fighting implementation
private var _health:Number = 100;
function doDamage(withWeapon:IEquipableWeapon) {
_health -= withWeapon.damage;
}
}
Затем вставьте их в свой подкласс MovieClip
для вашего Hero
.
public class Hero extends MovieClip {
private var _mover:IMoveable;
private var _fighter:IFightable;
public function Hero(mover:IMoveable, fighter:IFightable) {
_mover = move;
_fighter = fighter;
}
}
Здесь вы используете Hero
класс как диспетчер компонентов, так и компонент визуализации, что немного противоречит тому, о чем Уэст говорит в статье, но я отвлекся. Но идея заключается в том, что ваш менеджер (the Hero
) становится более или менее оркестратором, проксируя обратные вызовы, к которым применим любой компонент; методы вызова _mover
и fighter
для выполнения вашей фактической работы.
У такого подхода есть несколько преимуществ и некоторые недостатки. Во-первых, его сложнее настроить; это требует, чтобы вам действительно нравились компоненты и то, что будет делать каждый логический фрагмент кода. Но, с другой стороны, это отделяет ваши реализации друг от друга, делает его более тестируемым и пригодным для повторного использования. Вы также можете менять компоненты в любое время (во время компиляции или выполнения, если на то пошло), что дает вам некоторую гибкость при создании новых объектов.
Но в любом случае, это всего лишь предложение немного другой парадигмы, с которой вы, похоже, флиртуете. Возможно, вы получите от этого некоторый опыт. Но обязательно прочитайте статью, если вы еще этого не сделали.
Также изучите (например, ознакомьтесь с API) движок Unity, который имеет аналогичную модель агрегации и наследования, где интерфейсы являются ключом к абстракции.
Ответ №2:
Обычно вам требуется обычное определение класса, расширяющее movieclip, затем настройте свой герой movieclip на использование этого класса в параметрах экспорта для actionscript. Интерфейс, скорее всего, вообще не нужен для вашей игры.
Ответ №3:
Просто для пояснения — интерфейсы реализованы, а не унаследованы. Поэтому не имеет значения, какой тип класса вы создаете, который реализует iHero. Итак, чтобы создать тип библиотечного класса, который реализует Ihero, расширьте отображаемый объект, такой как Sprite или MovieClip, а затем используйте ключевое слово implements для указания класса, реализующего Ihero.
Добавьте методы Ihero, и теперь у вас есть класс объектов отображения, который реализует iHero. Это может выглядеть примерно так (обратите внимание, что функция конструктора не предоставляется)
package
{
import flash.display.Sprite;
import com.interfaces.IHero;
/**
* ...
* @author Zachary Foley
*/
public class MyDisplayObkect extends Sprite implements IHero
{
public function MoveLeft():void
{
// Add Implementation here;
}
public function MoveRight():void
{
// Add Implementation here;
}
public function MoveUp():void
{
// Add Implementation here;
}
public function MoveDown():void
{
// Add Implementation here;
}
//in battle
public function DoDamage(isCasting:Boolean):void
{
// Add Implementation here;
}
public function DoHeal():void
{
// Add Implementation here;
}
public function Flee():void
{
// Add Implementation here;
}
public function TakeDamage():void
{
// Add Implementation here;
}
public function IsAlive():Boolean
{
// Add Implementation here;
}
public function CheckDeath():void
{
// Add Implementation here;
}
public function Die():void
{
// Add Implementation here;
}
}
}