2013-03-06 63 views
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


PagerAdapter类在Android支持库有其实某种建筑这样的,但周围的其他方法:

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

旧代码怎么会使用吗?您引入了一种新的抽象方法,打破了所有现有的子类。 – 2013-03-06 22:52:52

+4

为什么你不能继续调用'doSomething(“hi”)'(带有抑制警告)或者只是调用'doSomething(“hi”,null)'? – 2013-03-06 22:53:04

+0

你可以在'myMethod()'中调用新的'doSomething(String,String)'。 – shuangwhywhy 2013-03-06 22:54:50

回答

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

+0

这看起来确实是理想的选择。我可以检查该类是否是NewFeature的子类,以决定调用哪个方法。事实上,我不需要在'NewFeature'的'doSomething()'方法中调用'doSomething(param,null)',因为它永远不会被调用? – nhaarman 2013-03-06 23:30:55

+0

是的 - 无论真的有意义。没有具体的例子就很难说。 – theon 2013-03-06 23:37:50

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 
} 
+0

尽管这会起作用,但我认为这给实施者增添了一些困惑。弃用该方法,但仍要求重写该方法。 – nhaarman 2013-03-06 23:31:20