2017-10-21 11 views
5

たとえば、私はObjectを返し、Objectをパラメータとして取るメソッドを持つProcessor基本クラスを持っています。私はそれを拡張し、Stringを返し、Stringをパラメータとして取るStringProcessorを作成したいと思います。ただし、 共変タイプは、戻り値でのみ許可されますが、パラメーターでは許可されません。そのような制限の理由は何ですか?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。 Processorクラスを設計するときは、「プロセッサは任意のObjectを引数としてとり、Objectを返すことができる」という契約書を作成します。

StringProcessorはプロセッサです。それで、その契約に従うことになっています。しかし、引数としてStringを受け入れるだけであれば、その契約に違反します。覚えておいてください:プロセッサは任意のObjectを引数として受け入れるはずです。

だからあなたが行うことができる必要があります:文字列オブジェクトである、それはオブジェクトを返すことになっていますので、すべてが正常である:文字列を返すとき

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

、それが契約に違反しません。

あなたはジェネリックを使用することによって達成するためにやりたいことができます:あなたは、タイプ理論的な答えをしたい場合は関数型のサブタイプの関係を検討する際

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

はまた、その理由は、あります、関係は、戻り値の型に共変ですが、引数の型に反変YWのサブタイプであるとUXのサブタイプである場合、すなわちX -> YU -> Wのサブタイプです)。

関連する問題