【问题标题】:How to override a function in a dynamic class with actionscript?如何使用 actionscript 覆盖动态类中的函数?
【发布时间】:2011-03-11 05:14:54
【问题描述】:

这是一个剧本应用程序。

我有两个班级:

public dynamic class Bullet extends Sprite {
   public function update():void {
      x += 5;
      y += 5;
   }
}

public class BulletFactory {
   public function createFastBullet:Bullet {
      var result:Bullet = new Bullet();

      result.update = function() {
         x += 10;
         y += 10;
      }
   }
}

这基本上就是我想要做的。在 actionscript 中实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: actionscript blackberry-playbook dynamic-class


    【解决方案1】:

    你不要那样做。动态是允许您添加任何尚未声明的临时属性,而不是覆盖已声明的函数。不要将动态与抽象混淆。

    试试这样的方法

    public class Bullet extends Sprite{
        public var speedX = 5;
        public var speedY = 5;
    
        public function update():void{
           x += speedX;
           y += speedY;
        }
    }
    
    public class BulletFactory{
    
        public static function getFastBullet():Bullet{
            var result:Bullet = new Bullet();
            result.speedX = result.speedY = 10;
            return result;
        }
    
    }
    

    根据您的喜好调整 speedX/speedY 的公开/私密可见性。

    另一方面,如果您想尽可能从字面意义上“动态地覆盖一个函数”,那么总有这个(这是 hacky 但有效)。

    public class AbstractBullet extends Sprite{
    
        public var update:Function; // <- Notice that function is just a variable here.
    
    }
    

    然后在您的子弹工厂中,您可以临时分配更新功能。请注意,这不太“安全”,因为您失去了所有类型安全的概念,因为更新不再具有集合签名。在调用它之前,您还必须确保它存在。如果你想避免编译器警告,你必须明确地检查空值。

    var f:Function;
    
    // this is fine.
    // it's particularly safe if 
    // f is a declared variable of type
    // Function.
    if(f != null) f();
    
    // this is also fine,
    // and is preffered if f is NOT
    // a defined variable but instead
    // a dynamically created (and therefore
    // untyped) variable of a dynamic object.
    // You would not want to "call" something
    // that is not a function, after all.
    if(f is Function) f();
    
    
    
    
    // but this gives a warning
    // even though the code works
    // correctly at runtime.
    if(f) f();
    

    【讨论】:

    • 使用 != null 来查看是否设置了 Function 很好,您不会收到编译器警告。我一直使用 Function 对象代替事件侦听器,因为它的速度大约快 1000 倍
    • @divillysuasages 我发现了我正在谈论的问题。它不是一个空检查,而是一个存在检查。 var f:函数;如果(f)f();将用这个修改答案。
    • 我实际上有另一种类型的子弹,称为 WaveBullet,它以正弦波移动,所以它不一定使用 speedX 和 speedY。
    • @Kenneth 在这种情况下,您将使用更经典的继承并创建一个单独的“WaveBullet”类,该类在 AS3 上下文中扩展 Bullet。正如我所提到的,在 AS3 中覆盖“抽象函数”的唯一方法是将其定义为 var f:Function = function(){trace("I'm a function");} 但这在 AS3 中并没有得到很好的支持就像创建一个新的特定派生类一样。
    【解决方案2】:

    您可以结合使用接口、扩展和覆盖来解决您的问题。 下面不会编译,但应该给你一个起点。

    public interface IBullet {
        function update():void
    }
    
    public class DefaultBullet extends Sprite implements IBullet{
       public function update():void {
          x += 5;
          y += 5;
       }
    }
    
    public class FastBullet extends DefaultBullet implements IBullet{
       override public function update():void {
          x += 10;
          y += 10;
       }
    }
    
    public class BulletFactory {
       public function createBullet(bulletType:String):IBullet {
          var bullet:IBullet;
          if(bulletType=="fast"){
            bullet = new FastBullet();
          }else{
            bullet = new DefaultBullet();
          }
          return bullet;
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-10
      • 2012-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多