web-dev-qa-db-fra.com

Manière de faire en sorte que la méthode de la classe parent Java renvoie l'objet de la classe enfant

Existe-t-il un moyen élégant de rendre la méthode Java située dans l'objet de retour de la classe parent de la classe enfant, lorsque cette méthode est appelée à partir d'un objet de la classe enfant?

Je veux implémenter ceci sans utiliser d'interfaces supplémentaires ni de méthodes supplémentaires, et l'utiliser sans casts de classes, arguments auxiliaires, etc.

Mettre à jour:

Désolé que je n'étais pas si clair.

Je veux implémenter le chaînage de méthodes, mais j'ai des problèmes avec les méthodes de classe parent: je perds l'accès aux méthodes de classe enfant lorsque j'appelle des méthodes de classe parent ... Je suppose que j'ai présenté l'essentiel de mon idée.

Les méthodes doivent donc renvoyer l'objet this de la classe this.getClass().

26
Timofey Gorshkov

Si vous recherchez simplement un chaînage de méthodes par rapport à une sous-classe définie, les éléments suivants devraient alors fonctionner:

public class Parent<T> {

  public T example() {
    System.out.println(this.getClass().getCanonicalName());
    return (T)this;
  }
}

ce qui pourrait être abstrait si vous voulez, puis quelques objets enfants qui spécifient le type de retour générique (cela signifie que vous ne pouvez pas accéder à childBMethod depuis ChildA):

public class ChildA extends Parent<ChildA> {

  public ChildA childAMethod() {
    System.out.println(this.getClass().getCanonicalName());
    return this;
  }
}

public class ChildB extends Parent<ChildB> {

  public ChildB childBMethod() {
    return this;
  }
}

et puis vous l'utilisez comme ça

public class Main {

  public static void main(String[] args) {
    ChildA childA = new ChildA();
    ChildB childB = new ChildB();

    childA.example().childAMethod().example();
    childB.example().childBMethod().example();
  }
}

la sortie sera

org.example.inheritance.ChildA 
org.example.inheritance.ChildA 
org.example.inheritance.ChildA 
org.example.inheritance.ChildB 
org.example.inheritance.ChildB
57
Gary Rowe

Qu'essayez-vous de réaliser? Cela semble être une mauvaise idée. Une classe de parents ne devrait rien savoir de ses enfants. Il semble terriblement près de briser le principe de substitution de Liskov . Mon sentiment est que votre cas d'utilisation serait mieux servi en modifiant la conception générale, mais difficile à dire sans plus d'informations.

Désolé de paraître un peu pédant, mais j'ai un peu peur quand je lis une telle question.

7
Guillaume

Simplement pour démontrer:

public Animal myMethod(){
  if(this isinstanceof Animal){
     return new Animal();
  }
  else{

     return this.getClass().newInstance();
  }
}
3
Jigar Joshi

Vous pouvez appeler this.getClass() pour obtenir la classe d'exécution.

Cependant, ce n'est pas nécessairement la classe qui a appelé la méthode (cela pourrait être encore plus bas dans la hiérarchie).

Et vous devez utiliser la réflexion pour créer de nouvelles instances, ce qui est délicat, car vous ne savez pas quel type de constructeur a la classe enfant.

return this.getClass().newInstance(); // sometimes works
2
Thilo

Je sais exactement ce que vous voulez dire. Dans Perl, il y a la variable $class qui signifie que si vous appelez une méthode de fabrique sur une sous-classe, même si elle n'est pas remplacée dans la sous-classe, si elle instancie une instance de $class, une instance de la sous-classe sera créé.

Smalltalk, Objective-C, de nombreuses autres langues ont une installation similaire.

Hélas, il n’existe pas de telles installations équivalentes en Java.

1
Adrian Smith
public class Parent {
    public Parent myMethod(){
        return this;
    }
}
public class Child extends Parent {}

Et l'invoque comme

       Parent c = (new Child()).myMethod();
       System.out.println(c.getClass());

Est-ce que cette solution est correcte? Si c'est le cas, en quoi est-ce différent de la solution n ° 1?

0
ch4nd4n