Java peut-il appeler la méthode parent substituée dans d'autres objets mais pas dans un sous-type?

StackOverflow https://stackoverflow.com/questions/1032847

  •  06-07-2019
  •  | 
  •  

Question

ici fonctionne le code java

class Cup {
    public String sayColor() {
        return "i have a color .";
    }
}

class TCup extends Cup{
    public String sayColor(){
        System.out.println(super.getClass().getName());
        return super.sayColor()+"color is tee green.";
    }
}

class MyTCup extends TCup {
    public String sayColor(){
        System.out.println(super.getClass().getName());
        return super.sayColor()+"but brushed to red now!";
    }
}
class Test {
    public static void main(String[] args) {
        Cup c = new MyTCup();
        System.out.print(c.sayColor());
    }
}

et l'exécution des impressions de la classe Test

MyTCup
MyTCup
i have a color .color is tee green.but brushed to red now!

question 1: Au moment de l'exécution, le type d'objet C est MyTCup, mais il peut toujours appeler la super méthode. Existe-t-il une pile de méthodes en mémoire dans MyTCup après l’initialisation de l’objet, puis peut appeler au moment de l’exécution, comme le code?

question 2: Il n'y a aucun moyen d'appeler la super méthode dans d'autres objets. Comme je le sais, c ++ peut appeler à tout moment la méthode parent. Pourquoi est-ce différent en Java?

Était-ce utile?

La solution

Vous ne pouvez pas appeler la super-méthode dans d'autres objets - cela violerait l'encapsulation. Le problème est que l'objet contrôle ce que font ses méthodes surchargées. Par exemple, vous pouvez redéfinir la méthode add d'une collection afin de générer une exception dans certaines circonstances, afin de ne garantir que le paramètre "valid". les articles ont été ajoutés à la collection. Ce serait inutile si les appelants pouvaient simplement le contourner avec un casting!

Un objet ne peut appeler lui-même super.foo () que pour permettre à un appel d'être implémenté à l'aide de l'implémentation parent. Il appartient au code de la classe de s’assurer qu’il ne le fait jamais que de façon sensée. Encore une fois, pour prendre l’exemple de add-in-a-collection, si la collection remplace add , elle devrait disposer de un moyen d'ajouter l'élément validé à la collection, ce qui cela ferait avec super.add () .

Notez que, pour la même raison d'encapsulation, vous ne pouvez appeler que votre implémentation parent, et non l'implémentation des grands-parents - donc super.foo () est valide, mais < code> super.super.foo () n'est pas.

Autres conseils

1:

Votre question n’est pas tout à fait claire. Qu'entendez-vous par "appeler au moment de l'exécution comme le code"? Si vous demandez comment instance c sait quelle est sa super classe, alors oui, la hiérarchie des classes est stockée en mémoire et la VM peut y accéder.

2:

Java vous permet effectivement de convertir une instance en parent. C'est juste que l'appel d'une méthode sur une instance utilise toujours la classe réelle de l'instance, pas sa classe à la compilation. C'est à dire. En Java, toutes les méthodes sont ce que l’on appellerait "virtuel". en C ++. Pourquoi cela a été décidé, je ne sais pas.

Éditer: En fait, Jon Skeet explique très bien pourquoi vous ne pouvez pas appeler une méthode d'une super classe sur une instance d'une sous-classe, alors je sais maintenant: -).

Vous pouvez définir une nouvelle méthode d'assistance dans la sous-classe afin de ne pas remplacer l'original - appelez-le - il peut appeler la super méthode ou non, selon vos préférences.

En fait, vous le pouvez, mais vous devez utiliser une méthodologie afin que cela ne fonctionne que sur votre code.
Dans la classe supérieure, ajoutez le paramètre "Classe". à la méthode, comme dans:

public String sayColor(Class classFilter){...

maintenant, à chaque remplacement, vous vérifiez si la sous-classe actuelle est celle du filtre spécifié comme:

if(TCup.class!=classFilter)return super.sayColor(classFilter);
return "some text for TCup only";

J'ai codé de manière exclusive. Vous pouvez ajouter plus de paramètres, ou comparer avec null, pour pouvoir joindre les résultats aux super classes, utilisez votre créativité:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top