2009-06-23 4 views
33

ici travaille code javaEst-ce que java peut appeler une méthode substituée par un parent dans d'autres objets mais pas sous-type?

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 classe de test

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

question 1: Au moment de l'exécution, l'objet type de C est MyTCup, mais il peut toujours appeler la méthode super Est-ce qu'il y a une pile de méthode dans la mémoire dans MyTCup après avoir initialisé l'objet, et puis peut appeler à 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 lancer à appeler la méthode parent à tout moment.Pourquoi la conception de Java comme ça?

+1

Vous devriez probablement accepter la réponse une fois que vous êtes satisfait :) –

Répondre

65

Vous ne pouvez pas appeler la super-méthode dans d'autres objets - cela viole l'encapsulation. Le point entier est que l'objet contrôle ce que font ses méthodes surchargées. Par exemple, vous pouvez remplacer la méthode add d'une collection pour lever une exception dans certaines circonstances, de sorte que seuls les éléments "valides" puissent être ajoutés à la collection. Ce serait inutile si les appelants pouvaient simplement le contourner avec une distribution! La seule raison pour laquelle un objet appelle super.foo() pour lui-même est de permettre à un appel d'être implémenté en utilisant l'implémentation parente. C'est au code de la classe de s'assurer que ça ne fait que ça. Encore une fois, pour prendre l'exemple add-in-a-collection, si la collection remplace add il faudrait une certaine façon d'ajouter l'élément validé à la collection, ce qui serait le cas avec super.add().

Notez que pour la même raison de encapuslation, vous pouvez seulement appeler votre implémentation mère, et non la mise en œuvre des grands-parents - si super.foo() est valide, mais super.super.foo() n'est pas.

+0

Voir aussi http: // stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java (que vous avez très bien répondu). –

+0

Et regardez ça ... J'ai utilisé le même exemple :) –

+0

Merci beaucoup pour votre réponse! Je pense que c'est le point. – sting

1

1:

Votre question n'est pas très claire. Que voulez-vous dire par "appeler à l'exécution comme le code"? Si vous demandez comment l'instance c sait ce qu'est sa super classe, alors oui, la hiérarchie de classe est stockée en mémoire et peut être accédée par la machine virtuelle.

2:

Java ne fait vous permet de jeter une instance à son 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 de compilation. C'est à dire. en Java, toutes les méthodes sont ce qu'on appellerait "virtuel" en C++. Pourquoi cela a été décidé je ne sais pas. 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 maintenant je sais :-).

+0

je veux dire la méthode "sayColor" appelée de MyTCup à TCup et Cup et la classe affichée est "MyTCup" .so les méthodes appartiennent à MyTCup ou ont appartenu TCup, Cup.Je ne connais pas jvm, peut-être tout dans la zone de méthode. – sting

0

Vous pouvez définir une nouvelle méthode d'assistance dans la sous-classe afin de ne pas remplacer l'original - appelez-le - elle peut appeler la super-méthode ou non, selon ce que vous voulez.

0

En fait, vous pouvez, mais vous devez utiliser une méthodologie, donc cela ne fonctionnera que sur votre code.
A la super classe, 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é d'une manière exclusive. Vous pouvez ajouter plus de paramètres, ou comparer avec null, de sorte que vous pouvez joindre des résultats avec les super classes, utilisez votre créativité :)