This is for a playbook app.
I have two classes:
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;
}
}
}
开发者_C百科This is essentially what I'm trying to do. What's the best way to achieve this in actionscript?
You don't do it that way. Dynamic is to allow you to add any ad-hoc property that isn't already declared, not to override already declared functions. Dynamic is not to be confused with abstract.
Try something like this instead
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;
}
}
Adjust the public/private visibility of speedX/speedY to your liking.
If on the other hand you want to "dynamically override a function" in as literal a sense as possible, there's always this (which is hacky but valid).
public class AbstractBullet extends Sprite{
public var update:Function; // <- Notice that function is just a variable here.
}
Then in your bullet factory you can assign the update function on an ad-hoc basis. Note that this is less "secure" as you lose all notion of type safety as update no longer has a set signature. You also have to make sure it exists before you call it. You must make the null check explicit if you want to avoid a compiler warning.
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();
You could solve your issue using a combination of Interfaces, extensions and overrides. The below won't compile, but should give you a starting point.
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;
}
}
精彩评论