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 倾向于在它们第一次被宣传为已弃用之后删除整个版本的方法。

于 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);
}

现有的子类仍然可以工作,但会处于“降级”模式,其中第二个参数总是被忽略。

新的子类将简单地通过以下方式实现:

@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 回答