2

抽象メソッドを持つ抽象クラスを持つライブラリがあるとします。

public abstract class MyAbstractClass{

    public void myMethod(){
        int a = doSomething("hi");
    }

    public abstract void doSomething(String param);
}

ここで、メソッドにパラメーターを追加することにしましたが、古いコードを使用できるように、古いメソッドの機能を維持したいと思います。

public void myMethod(){
    int a = ?
}

/**
 * @deprecated use doSomething(String, String) instead.
 */
@Deprecated
public int doSomething(String param){ return doSomething(param, null); }

public abstract int doSomething(String param, String secondParam);

myMethodこのシナリオで自分をどのように実装しますか?


AndroidサポートライブラリのPagerAdapterクラスには、実際にはこのような構造がありますが、その逆です。

public Object instantiateItem(ViewGroup container, int position) {
    return instantiateItem((View) container, position);
}

/**
 * @deprecated Use {@link #instantiateItem(ViewGroup, int)}
 */
public Object instantiateItem(View container, int position) {
    throw new UnsupportedOperationException(
            "Required method instantiateItem was not overridden");
}

この振る舞いはやめるべきですか?そして、この構造を使用する場合、どのメソッドを呼び出すかをどのように知ることができますか?

4

2 に答える 2

2

私はあなたの苦境を見ていると思います。ライブラリに抽象クラスがあり、その抽象メソッドをサブクラス化して実装しています。このメソッドを非推奨にし、代わりに今後実装する必要がある新しい抽象メソッドを追加します。

これが私がすることです:

Featureライブラリのユーザーがサブクラス化しているクラスから開始します

public abstract class Feature {
    public abstract void doSomething(String param);
}

Featureクラスはほとんどそのままにしておきますが、メソッドを廃止し、ドキュメントで、人々がそのクラスの代わりにサブクラス化して、光沢のある新しい抽象メソッドを実装する必要があることを宣伝しNewFeatureますFeature。サブクラス化する既存のコードFeatureは引き続き機能します。

public abstract class Feature {
    /**
      @deprecated Extend NewFeature instead and implement doSomething(a, b) 
    */
    @Deprecated
    public abstract void doSomething(String param);
}

public abstract class NewFeature extends Feature {

    @Deprecated
    @Override
    public void doSomething(String param) {
        doSomething(param, null);
    }

    public abstract void doSomething(String param, String paramTwo);
}

さらに将来的に

十分な時間が経過したら、Featureクラスを削除できます。たとえば、Springは、非推奨として最初にアドバタイズされた後、メソッド全体を1つのバージョンで削除する傾向があると思います。

于 2013-03-06T23:19:11.103 に答える
0

コメントに基づいて、代わりに次のようにします。

public void myMethod(){
    int a = doSomething("hi", "theOptimalSecondArgumentValue");
}

/**
 * @deprecated use doSomething(String, String) instead.
 */
@Deprecated
public abstract int doSomething(String param);

/**
 * Delegates to {@link #doSomething(String)} and thus ignores the second argument 
 * by default. Subclasses should override this method to return a better result,
 * taking the second argument into account
 */
public int doSomething(String param, String secondParam) {
    return doSomething(param);
}

既存のサブクラスは引き続き機能しますが、2番目の引数が常に無視される「劣化」モードになります。

新しいサブクラスは、次の方法で簡単に実装できます。

@Override
public int doSomething(String param) {
    doSomething(param, "theOptimalDefaultValue");
}

@Override
public int doSomething(String param, String secondParam) {
    // compute the result using the two arguments
}
于 2013-03-06T23:20:44.620 に答える