2011-02-17 58 views
3

我不熟悉」泛型「。它是否正確使用「<T extends SuperClass>」?你是否同意使用泛型後的代碼更好?正確使用「<T extends SuperClass」「

Before using Generics 
================================================= 

public abstract class SuperSample { 

    public void getSomething(boolean isProcessA) { 
     doProcessX(); 
     if(isProcessA){ 
      doProcessY(new SubASample()); 
     }else{ 
      doProcessY(new SubBSample()); 
     } 
    } 

    protected abstract void doProcessX(); 

    protected void doProcessY(SubASample subASample) { 
     // Nothing to do 
    } 

    protected void doProcessY(SubBSample subBSample) { 
     // Nothing to do 
    } 

} 

public class SubASample extends SuperSample { 

    @Override 
    protected void doProcessX() { 
     System.out.println("doProcessX in SubASample"); 
    } 

    @Override 
    protected void doProcessY(SubASample subASample) { 
     System.out.println("doProcessY in SubASample"); 
    } 

} 

public class Sample { 

    public static void main(String[] args) { 
     SubASample subASample = new SubASample(); 
     subASample.getSomething(true); 
    } 

} 

After using Generics 
================================================= 

public abstract class SuperSample { 

    public void getSomething(boolean isProcessA) { 
     doProcessX(); 
     if(isProcessA){ 
      doProcessY(new SubASample()); 
     }else{ 
      doProcessY(new SubBSample()); 
     } 
    } 

    protected abstract void doProcessX(); 

    protected abstract <T extends SuperSample> void doProcessY(T subSample); 

} 

public class SubASample extends SuperSample { 

    @Override 
    protected void doProcessX() { 
     System.out.println("doProcessX in SubASample"); 
    } 

    @Override 
    protected <T extends SuperSample> void doProcessY(T subSample) { 
     System.out.println("doProcessY in SubASample"); 
    } 

} 

public class Sample { 

    public static void main(String[] args) { 
     SubASample subASample = new SubASample(); 
     subASample.getSomething(true); 
    } 

} 

回答

4

如果你想要做什麼,我想想做的事,我不認爲這是正確的方式(*)。如果您希望每個子類中需要實現的是處理它自己的類型的方法,那麼你可以使用CRTP招:

abstract class Super<S extends Super<S>> { 
    abstract void process(S s); 
} 

class SubA extends Super<SubA> { 
    void process(SubA s){ /* do something */ } 
} 

class SubB extends Super<SubB> { 
    void process(SubB s){ /* do something */ } 
} 

注意,這種模式強制子類的一般特徵,例如class SubA extends Super<SubB>不會編譯。

順便說一下,Java本身在java.lang.Enum中使用那個技巧。

(*)如果這不是您想強制執行的行爲,請澄清。

+0

的確,我必須在所有子類中實現該方法,如果我使用它..我會照顧情況。和CRTP技巧..我從來不知道這一點。謝謝我會檢查出來。 – zono 2011-02-17 15:33:07

+1

`class SubA extends Super `compiles,given`class SubB extends Super ` – irreputable 2011-02-17 16:25:55

1

這是正確的使用。這意味着您將類型T限制爲SuperSample的子類。對於第二個答案,是的,我認爲使用generecis的代碼更好,因爲它可以防止錯誤地使用容器(例如List ...)進行類型轉換。但實際上Java中的泛型只是語法suger,所以它們在運行時被擦除。

相關問題