2013-03-06 67 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