2017-10-21 116 views
5

例如我有一個處理器基類與返回一個對象,並採取對象作爲參數的方法。我想擴展它,並創建一個StringProcessor將返回字符串,並採取String作爲參數。然而 協打字只能用返回值,但不允許參數。這種限制的原因是什麼?在Java方法重載爲什麼允許有協變返回類型,但不是協變的參數?

class Processor { 
    Object process (Object input) { 
     //create a copy of input, modify it and return it 
     return copy; 
    } 
} 

class StringProcessor extends Processor { 
    @Override 
    String process (String input) { // permitted for parameter. why? 
     //create a copy of input string, modify it and return it 
     return copy; 
    } 
} 

回答

10

The Liskov principle。在設計處理器類,你寫一份合同說:「一個處理器能夠使用任何對象作爲參數,並返回一個對象」。

的StringProcessor是處理器。所以它應該遵守這個合同。但是,如果它僅接受String作爲參數,則違反了該合同。請記住:處理器應該接受任何對象作爲參數。

所以,你應該能夠做到:

StringProcessor sp = new StringProcessor(); 
Processor p = sp; // OK since a StringProcessor is a Processor 
p.process(new Integer(3456)); 

當返回一個字符串,它不違反合同:它應該返回一個對象,一個String是一個對象,所以一切都很好。

你可以做你想要達到的目標,通過使用泛型:

class Processor<T> { 
    Object process (T input) { 
     //create a copy of input, modify it and return it 
     return copy; 
    } 
} 

class StringProcessor extends Processor<String> { 
    @Override 
    String process (String input) { 
     return copy; 
    } 
} 
0

另外,如果你想有一個類型的理論回答,這樣做的原因是,考慮到函數類型的子類型關係的情況下,關係是在返回類型協變,但在參數類型逆變(即X -> YU -> W亞型如果YW亞型和UX一個子類型)。

相關問題