0

私は 2 つのクラスを持っていますderivedClassAderivedClassBどちらも拡張parentClass して宣言しています。var o:parentClass次に、何が起こっているかに応じてo、タイプderivedClassAまたはderivedClassB.

基本的に、これは:

var o:parentClass  

...  

if(shouldUseA)  
    o = new derivedClassA();  
else  
    o = new derivedClassB();  
o.doSomething();

しかし、それは機能していません。あらゆる種類のエラーが発生しています。これがクラス継承のしくみではないでしょうか。何か本当に根本的なことが欠けているように感じますが、何が原因なのかわかりません。代わりにインターフェイスを使用することになっていますか? 私がやりたいことをする別の方法はありますか?

明確化のための編集:
-では public としてdoSomething()定義されparentClass、派生クラスではoverride public function doSomething()
- とエラーが発生します。および「タイプ derviedClassA の値の無関係なタイプのparentClassへの暗黙の強制」

4

3 に答える 3

1

私は以前にこれを行ったことがあります。誤って呼び出したときに明らかに指摘するために、基本クラスの仮想関数であることを意味するものにエラーをスローします。抽象基本クラスを作成するときにこれを行います。

Main.as (ドキュメント クラス)

package
{
    import flash.display.Sprite;

    public class Main extends Sprite
    {
        private var superClassRef:SuperClass;
        private var idLikeToBuyAnA:Boolean = true;

        public function Main()
        {
            trace("Main()");
            if (idLikeToBuyAnA)
            {
                superClassRef = new DerivedClassA();
            }
            else
            {
                superClassRef = new DerivedClassB();
            }

            superClassRef.doSomething();
        }
    }
}

SuperClass.as

package
{
    public class SuperClass
    {
        public function SuperClass()
        {
        }

        public function doSomething():void
        {
            throw new Error("Override me, I wish I were virtual!");
        }
    }
}

DerivedClassA.as

package
{
    public class DerivedClassA extends SuperClass
    {
        public function DerivedClassA()
        {
        }

        override public function doSomething():void
        {
            trace("I'm and A!");
        }
    }
}

DerivedClassB.as

package
{
    public class DerivedClassB extends SuperClass
    {
        public function DerivedClassB()
        {
        }

        override public function doSomething():void
        {
            trace("I'm a B!");
        }
    }
}
于 2011-03-29T01:51:01.470 に答える
0

あなたが求めていることを実行できるようにインターフェイスを作成します。これにより、変数をキャストする必要がなくなり、doSomething 関数にアクセスできるようになります。構造を使用した小さな例を次に示します。すべてのクラスが同じルート パッケージにあることに注意してください。したがって、インポート ステートメントはありません。

MainApp.as (これはデフォルトのアプリケーションです)

package  
{
    import flash.display.Sprite;

    public class MainApp extends Sprite 
    {
        private var parentClass : IParent;
        private var doA : Boolean = false;

        public function MainApp()
        {

            if (doA)
            parentClass = new DerivedClassA();
            else
            parentClass = new DerivedClassB();

            parentClass.doSomething();
        }
    }
}

親として

package  
{
    import flash.display.Sprite;

    public class Parent extends Sprite
    {
        public function Parent()
        {
        }
    }
}

DerivedClassA.as

package  
{
    public class DerivedClassA extends Parent implements IParent
    {
        public function DerivedClassA()
        {
            super();
        }

        public function doSomething() : void 
        {
            trace (this + " done something");
        }
    }
}

DerivedClassB.as

package  
{
    public class DerivedClassB extends Parent implements IParent
    {
        public function DerivedClassB()
        {
            super();
        }

        public function doSomething() : void 
        {
            trace (this + " done something");
        }
    }
}

IParent.as

package  
{
    public interface IParent 
    {
        function doSomething():void;
    }
}

ご覧のとおり、Interface の使用を参照してください。キャストなしで関数 doSomething を呼び出します。変数のキャストに問題はありませんが、これにより、より構造化されたコードが得られ、インターフェイスを実装するクラスに doSomething メソッドがあることが保証されます。それが役に立てば幸いです... G運

于 2010-06-17T09:43:45.037 に答える