0

これはすべてJBox2D(Javaの場合)のコンテキストにあります。Worldクラスは、関数を使用してBodyインスタンスを作成します。私は自分のアプリケーションのためにBodyにもう少し多くのものを追加しようとしています。この質問では、本文はComplexClassWithLotsOfAPIで表されます。

これが一般的な質問です。クラスを拡張して、事前に作成されたクラスにもう少し機能を追加しようとしています。私はこのようなことをしたいと思っています:

class SomeMore extends ComplexClassWithLotsOfAPI{
    int myExtraInt;
    //A bit more API functions
}

私がこれを行うために:

SomeMore sm=new SomeMore();
sm.someOldAPI();
sm.butAlsoMyNewAPI();

問題は、このComplexClassWithLotsOfAPIが、変更できない別のクラス(元のコンテキストではWorldクラス)によって作成されているため、単に自分で作成しているのではないことです(そうでない場合は、これで機能します)。ComplexClassWithLotsOfAPIから始めなければならないので、スーパークラスからサブクラスを構築する方法を探していましたが、スーパークラスをサブクラスにキャストする例はたくさんあります(ただし、これはここでは当てはまりません)。完了する必要のある関数の例を次に示します。

public SomeMore create(...){ 
    ComplexClassWithLotsOfAPI ccwlao=myWorld.create(...);
    SomeMore sm;
    //??
    return sm;
}

ラッピングの代わりに? 私の元々の解決策は、ComplexClassWithLotsOfAPIを自分のクラスに含めることでした。新しいクラスを作成するには、古いクラスを新しいコンストラクターに渡して、次の手順に進みます。

class SomeMore{
    public ComplexClassWithLotsOfAPI ccwloa;
    int myExtraInt;
    public SomeMore(ComplexClassWithLotsOfAPI nccwloa){
        ccwloa=nccwloa;
        myExtraInt=0;
    }
    //A bit more API functions
}
public SomeMore create(...){ 
    ComplexClassWithLotsOfAPI ccwlao=myWorld.create(...);
    SomeMore sm=new SomeMore(ccwlao);
    return sm;
    //OR more simply
    //return new SomeMore(myWorld.create(...));
}

しかし、古いAPIにアクセスするには、次のことを行う必要があります。

SomeMore sm=new SomeMore();
sm.ccwloa.someOldAPI();
sm.butAlsoMyNewAPI();

私は少し不合理かもしれませんが、この種の機能は退屈であり、それを必要としないものにそれだけ多くの複雑さを追加します。つまり、誰かがもう少し機能を追加したい場合、彼らは私のクラスをさらに別のクラスにラップし、古いAPIを取得するために3つのクラス階層を通過させるでしょうか?また、古いクラスのすべてのAPIを新しいクラスにラップするのは無駄に感じるでしょう(それらはたくさんあります)。

sm.someOldAPIButWrappedInMyClass(); //not desirable

ComplexClassWithLotsOfAPIのJavaファイルにはアクセスできず、コンパイルされたクラスファイルにしかアクセスできません。古いクラスに変更を強制することはできません(できたとしても、とにかくしたくないのですが)。私はJavaに比較的慣れていないので、おそらくこれはこれを行うための最良/適切な方法ではありませんが、代替手段を見つけることができませんでした。

4

1 に答える 1

1

Eclipseは、あるクラス(つまり、Parent)のサブクラスであり、フィールドに「Parent」のインスタンスを保持するデリゲートクラス(デリゲートと呼ばれる)を構築し、「Parent」のすべてのメソッドをオーバーライドするメソッドを生成できます。被委任者の同じ方法。その後、独自のメソッドを追加できます。

これは、コンテキストメニューの[ソース]オプションから行い、デリゲートメソッドを生成します。コードジェネレーターを機能させるには、サブクラスを作成して「Parent」を拡張し、「Parent」タイプのフィールドを作成する必要があります。

次に例を示します。

/** Example class delegating to a contained variable */
public class DelegatingComparator implements Comparator<String> {
    // Delegatee has to be present before letting Eclipse generate
    private Comparator<String> delegatee;

    /** My own method extends Comparator methods */
    public int compareToFoo(String o1) {
        return compare(o1, "foo");
    }

    /** Generated by Eclipse. Source > Generate getters and setters */
    public void setDelegatee(Comparator<String> delegatee) {
        this.delegatee = delegatee;
    }

    /** Generated by Eclipse. Source > Generate Delegate Methods */
    public int compare(String o1, String o2) {
        return delegatee.compare(o1, o2);
    }

    /** Generated by Eclipse. Source > Generate Delegate Methods */
    public boolean equals(Object obj) {
        return delegatee.equals(obj);
    }

}
于 2013-01-18T22:54:39.857 に答える