2012-02-26 6 views
1

いくつかの関数、セッター、ゲッターをオーバーライドするDisplayObjectのカスタムバージョンを作成します。例:AS3の継承と多相形

public class MyDisplayObject extends DisplayObject{ 
    .... 
    override public function get x():Number{ 
     return 123; 
    } 
    .... 
} 

、今、私はちょうどそれがmyDisplayObjectという代わりにしたDisplayObjectから継承違いは、MovieClipのと同じことになっているクラスMyMovieClipを、生成したいです。 MovieClipの実装全体をコード化しなくても簡単に行うことができますか(実際には不可能です)?

+5

あなたはおそらく継承よりも構図を使ってクラスを作成する方がよいでしょう。申し訳ありませんが、あまり答えはありませんので、私はちょうどコメントに入れました。 –

答えて

1

ActionScript 3内で多重継承を偽装する方法は、outlined hereとなっています。基本的には、外部ASファイルを別のクラスに直接インポートすることです。それはかなりかエレガントではありませんが、すべての目的と目的のために、潜在的な解決策です。もちろん

あなたがmyDisplayObjectというのうち、カスタムコードを取る必要がありますので、インターフェースは(おそらくMyInterfaceと呼ばれる?)別のインタフェースで、その後myDisplayObjectという両方にそれを実装することを場所(から延びる、別のクラスを拡張することはできませんDisplayObject)とMyMovieClip(MovieClipから拡張)を、上記のWebサイトで説明した手法を使用して作成します。

3

ActionScriptでは実際の多重継承はありません。しかし、パフォーマンスが低下している場合は、Proxyクラスを拡張してシミュレーションすることができます。

Proxyを継承するクラスを作成し、任意のタイプのObjectインスタンスを保持し、コンストラクタを使用してそのタイプを渡します。プロパティのすべての呼び出しは、呼び出しを除いてそのインスタンスに転送されますxへ:

package 
{ 
    import flash.display.MovieClip; 
    import flash.utils.Proxy; 
    import flash.utils.flash_proxy; 


    public dynamic class MyMovieClip extends Proxy 
    { 
     private var mc:*; 

     private function get differentX():Number { 
      return 123; 
     } 

     private function set differentX(x:Number):void { 
      trace("value received:"+x); 
     } 

     override flash_proxy function getProperty(name:*):* { 
      if(name == "x") return differentX; 
      else return mc[name]; 
     } 

     override flash_proxy function setProperty(name:*, value:*):void { 
      if(name == "x") differentX = value; 
      else mc[name] = value; 
     } 

     public function MyMovieClip (clazz:Class = MovieClip) { 
      if (clazz) mc = new clazz(); 
     } 
    } 
} 

の使用方法: - あなたは、たとえば、表示リストにプロキシを追加することはできません明らかに

var mc : MyMovieClip = new MyMovieClip(Sprite); 

mc.x = 1000; // traces "value received:1000" 
trace ("value returned:" + mc.x); // 123; 

、しかし、このアプローチは、プロキシ上で呼ばれる方法に限定されるものです。

これに実際に参加したい場合は、as3commons bytecode libraryをチェックして、実行時にAVM2が使用する実際のバイトコードを操作することもできます。 aspect-oriented programmingの場合はgenerating dynamic proxiesに使用できます。

1

私はあなたが構成と継承の組み合わせを使用することを提案します。要するに:

  1. 対応する内蔵から直接
  2. 継承(IS-A)に実際のカスタムのDisplayObject、ムービークリップなどのクラスを作成するクラスの並列直列にあなたの「余分な」機能を構築また、対応するエクステンションクラスのHAVE-A(の構成)のインスタンスです。カスタムクラスのメンバーを追加または上書きするには、単一行ラッパーを拡張クラスに追加するだけです。

私は確かにイラストが役に立つと思うので、ここにあります。私の拡張クラスはお互いに継承しているので(チェーンの下にすべて適用したいものを書き直す必要はありません)、 "使用可能な"クラスはFlashクラスを継承しています。そして、それは、各使用可能なクラスにラッパー数行のコードをコピー&ペーストすることが非常に簡単です:それはAS3でのいくつかの不規則な事柄を扱っ伴うためのDisplayObjectと

// Base EXTENSION class. Doesn't inherit from anything 
package { 
    import flash.display.DisplayObject; 
    public class DisplayObjectExtensions { 
     private var _displayObject:DisplayObject; 
     public function DisplayObjectExtensions(displayObject:DisplayObject){ 
      _displayObject = displayObject; 
     } 

     // Change the y property to be distance from bottom of stage 
     public function get y():Number { 
      return _displayObject.stage.stageHeight - _displayObject.y; 
     } 

     public function set y(value:Number):void { 
      _displayObject.y = _displayObject.stage.stageHeight - value; 
     } 

     // A brand new property 
     private var _customProperty:String; 
     public function get customProperty():String { return _customProperty; } 
     public function set customProperty(value:String):void { _customProperty = value; }  
    } 
} 

// MovieClip EXTENSION class. Inherits from base EXTENSION class: 
package { 
    import flash.display.MovieClip; 
    public class MovieClipExtensions extends DisplayObjectExtensions { 
     private var _movieClip:MovieClip; 
     public function MovieClipExtensions(movieClip:MovieClip) { 
      super(movieClip); 
      _movieClip = movieClip; 
     } 
     // Adding custom logic to the gotoAndPlay method 
     function gotoAndPlay(frame:Object, scene:String = null):void { 
      trace("Skipping to frame " + frame + 
        " in movie clip with customProperty = " + super.customProperty); 
      _movieClip.gotoAndPlay(frame, scene); 
     } 
    } 
} 

// Useable DisplayObject class: Inherits from flash DisplayObject, has wrappers 
// for extended functionality contained in EXTENSION class. 
package { 
    import flash.display.DisplayObject; 
    public class MyDisplayObject extends DisplayObject { 
     private var _extensions:DisplayObjectExtensions; 
     public function MyDisplayObject() { 
      _extensions = new DisplayObjectExtensions(this); 
     } 
     public override function get y():Number { return _extensions.y; } 
     public override function set y(value:Number) { _extensions.y = value; }; 
     public function get customProperty():String { return _extensions.customProperty; } 
     public function set customProperty(value:String):void { _extensions.customProperty = value; } 
    } 
} 

// Useable MovieClip class: Inherits from Flash MovieClip, only needs 
// to duplicate wrapper stubs to "inherit" all the custom extensions. 
package { 
    import flash.display.MovieClip; 
    public class MyMovieClip extends MovieClip { 
     private var _extensions:MovieClipExtensions; 
     public function MyMovieClip() { 
      _extensions = new MovieClipExtensions(this); 
     } 

     // Copy and paste wrappers from MyDisplayObject 
     public override function get y():Number { return _extensions.y; } 
     public override function set y(value:Number) { _extensions.y = value; }; 
     public function get customProperty():String { return _extensions.customProperty; } 
     public function set customProperty(value:String):void { _extensions.customProperty = value; } 

     // Plus the MovieClip-specific override: 
     public override function gotoAndPlay(frame:Object, scene:String = null):void { 
      _extensions.gotoAndPlay(object, scene); 
     } 
    } 
} 
0

あなたの例では、あまりにも複雑です。 DisplayObjectは抽象クラスで、AS3コードでは拡張できません。最も近いのはSpriteです。

拡大表示オブジェクト、特に表示オブジェクトを拡張することに関して、私は口笛のように聞こえませんが、とにかくこの質問をします。本当にそれが本当に欲しいのですか?そのようなトラブルはたくさんあります。 100以上のメソッドを持つクラスを継承することで、クラスが作成される可能性があります。そのクラスは完全に制御したり理解したりすることはほとんどありません。これはAS3で(歴史的に)行うべき共通のものですが、開発とメンテナンスに関して貴重な費用がかかるでしょう。前に説明したように、構図を使用するか、MovieClipのバージョンと組み込みのバージョンのいくつかの側面や相違点に特化したユーティリティメソッドを使用することを検討してください。

しかし、一般に、全く別のアプローチがありますが、それは全く同じではありませんが、構成に非常に似ています。あなたはそれを「デコレータ」と考えることができますが、正確に同じではありません。アイデアは、メソッドの実装が含まれていないクラスを持つ代わりに、実装が実行時に提供されることを期待しているということです。以下の例を考えてみましょう。

public class ClassWithDecorator 
{ 

    public function ClassWithDecorator(decorator:Vector.<Function>) 
    { 
     super(); 
     this._decorator = decorator; 
    } 

    public function classMethod(integer:int, string:String):Boolean 
    { 
     return this._decorator[0].apply(this, [integer, string]); 
    } 

} 

これにより、クラスごとに異なるメソッドセットを提供することで、さまざまな種類の類似オブジェクトを考慮に入れることができます。これは型定義の点では厳密ではありません。関数型の型を "緩める"ためですが、型が一致しないと実行時に通知されます。まあ、これはトレードオフです。

もう1つの欠点 - 必要なメソッドを実装していても、事前定義された型が必要な場所でこのクラスのインスタンスを「覗き見」することはできません。それでも、オブジェクトの種類が多い場合や、コードを記述するときに予測できない場合、これは実行可能なソリューションです。

0

MovieclipはDisplayObject
から継承しています。実際にはMovieClipを拡張して、DisplayObjectクラスのすべてのメソッドを継承するだけです。

フレームメソッドを使用していない場合は、MovieClipの代わりにSpriteを使用することをおすすめします。

MovieClip->Sprite->DisplayObjectContainer->InteractiveObject->DisplayObject->EventDispatcher->Object 


public class MyDisplayObject extends MovieClip{ 
    .... 
    override public function get x():Number{ 
     return 123; 
    } 
    .... 
}