web-dev-qa-db-fra.com

Remplacer une méthode avec différents types de retour en java?

J'ai lu un livre et il est dit que je peux remplacer une méthode si elle porte la même signature. selon le livre, la signature d'une méthode est Method_Name + paramètres passés.

selon le livre, je peux remplacer une méthode qui a différents types de retour. Est-il réellement possible de remplacer une méthode avec un type de retour différent en Java? parce que j’ai fait quelques recherches sur le net, j’ai trouvé des gens qui disaient que pour remplacer une méthode, le type de retour devait être identique.

selon le livre, il est également indiqué que Java générera une erreur de compilation lorsque nous essayons de surcharger une méthode avec le même nom et les mêmes paramètres mais avec des types de retour différents, car la signature ne désigne que le nom et les paramètres de la méthode. Si cela est vrai, nous devrions pouvoir remplacer une méthode avec un type de retour différent.

S'il vous plaît aidez-moi à comprendre cela. Merci d'avance.

18
nzhmz

Vous pouvez renvoyer un type différent, à condition qu'il soit compatible avec le type de retour de la méthode remplacée. Compatible signifie: il s'agit d'une sous-classe, d'une sous-interface ou d'une implémentation de la classe ou de l'interface renvoyée par la méthode remplacée.

Et c'est logique. Si une méthode renvoie un animal et que votre classe dérivée renvoie une vache, vous ne rompez pas le contrat de la méthode de la superclasse, car une vache est un animal. Si la classe dérivée retourne une banane, ce n'est plus correct, car une banane n'est pas un animal.

25
JB Nizet

Votre classe de parents a fait une promesse au monde extérieur. Par exemple, la méthode:

public Price calculatePrice(Items[] items).

Il dit au monde d'attendre un prix.

Si vous améliorez cette fonctionnalité dans votre sous-classe, vous devez toujours conserver les promesses originales de votre classe parent.

Vous pouvez ajouter des méthodes de calcul surchargées:

public Price calculatePrice(Items[] items, Integer minimumCharge).

Vous pouvez même améliorer les promesses de vos parents en utilisant un type de retour PLUS spécifique:

public AccuratePrice calculatePrice(Items[] items, Integer minimumCharge).

Mais vous devez au moins renvoyer le type que votre parent a promis… .. Il en va de même pour Exceptions dans la déclaration de la méthode.

11
David Lavender

Oui, cela est possible depuis Java 5, il est appelé type de retour covariant. Le type de retour doit être une sous-classe du type de retour de la méthode super class (les types primitifs ne sont pas autorisés). Exemple 

class X implements Cloneable {

    @Override
    protected X clone() {
        try {
            return (X) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new Error(e); // can never happen
        }
    }
}
3
Evgeniy Dorofeev

Votre méthode remplacée peut avoir le même type ou le sous-type de type de retour d'origine appelé retour covariant.

Si vous modifiez le type de retour de la méthode remplacée par quelque chose d'autre qui n'est pas un sous-type du type d'origine, vous obtiendrez une erreur lors de la compilation.

1
PermGenError

Voici un exemple:

class Base {
    public Number test() {
        return 0;
    }
}

class A extends Base {
    public Long test() {
        return 1L;
    }
}
1
jdb
// Covariant Overriding 
public class Parent {

  public Parent(){}
  String parentName;
  public Parent(String parentName){
    this.parentName=parentName;
    System.out.println(this.parentName);
 }

public  Parent show(){
    return new Parent("Parent");
}
}




public class Child extends Parent{

  public Child(){}
  String name;
  public Child(String name){
    this.name=name;
    System.out.println(this.name);
  }
  public Child show(){
    return new Child("Child");
}
}



public class Main {

public static void main(String[] args) {
    Parent parent=new Child();
    parent.show();

    Parent parent1=new Parent();
    parent1.show();
}
}
0
Deepak
Yes we can override different return types but they should be subclass.

public class Shape {
    public Shape area(Integer i) {
        System.out.println("Sape Area");
        System.out.println("Integer");
        return null;
    }
}


package com.oops;

public class Circle extends Shape {
    public Circle area(Integer i) {
        System.out.println("Circle Area");
        System.out.println("int");
        return null;
    }
}
0
shwetank