2017-10-21 47 views
5

Par exemple, j'ai une classe de base Processeur avec une méthode qui renvoie un objet et prend l'objet en tant que paramètre. Je veux l'étendre et créer un StringProcessor qui retournera String et prendra String comme paramètre. Cependant typage covariant est seulement autorisé avec la valeur de retour, mais pas de paramètre. Quelle est la raison de ces limitations?Pourquoi dans la méthode java, la substitution permet d'avoir des types de retour covariants, mais pas des paramètres covariants?

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; 
    } 
} 

Répondre

10

The Liskov principle. Lors de la conception de la classe Processor, vous écrivez un contrat disant: "un processeur est capable de prendre n'importe quel objet comme argument, et de retourner un objet".

Le StringProcessor est un processeur. Donc, c'est censé obéir à ce contrat. Mais s'il n'accepte que String comme argument, il viole ce contrat. Rappelez-vous: un processeur est supposé accepter n'importe quel objet comme argument.

Donc, vous devriez être en mesure de le faire:

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

Lors du retour d'une chaîne, il ne viole pas le contrat: il est censé retourner un objet, une chaîne est un objet, donc tout va bien.

Vous pouvez faire ce que vous voulez réaliser en utilisant les génériques:

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

Aussi, si vous voulez une réponse de type théorique, la raison en est, lorsque l'on considère la relation de sous-typage sur les types de fonction, la relation est covariant sur les types de retour, mais contravariant sur les types d'arguments (c.-à-X -> Y est un sous-type de U -> W si Y est un sous-type de W et U est un sous-type de X).