Il metodo sovrascritto del genitore può chiamare java in altri oggetti ma non in un sottotipo?

qui sta lavorando il codice 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()); } } 

e eseguendo le stampe della class Test

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

domanda 1: Al runtime, il tipo di object C è MyTCup, ma può sempre chiamare il metodo super. C’è una pila di metodi nella memoria in MyTCup dopo l’inizializzazione dell’object e quindi può richiamare in fase di runtime come il codice?

domanda 2: Non c’è modo di chiamare il metodo super in altri oggetti. Come so, c ++ può lanciare per chiamare il metodo genitore in qualsiasi momento. Perché il design java come questo?

Non puoi chiamare il metodo super in altri oggetti – questo violerebbe l’incapsulamento. L’intero punto è che l’object controlla quali sono i suoi metodi sovrascritti. Ad esempio, potresti sovrascrivere il metodo di add una raccolta per generare un’eccezione in determinate circostanze, in modo da garantire che solo gli elementi “validi” vengano aggiunti alla raccolta. Sarebbe inutile se i chiamanti potessero semplicemente bypassarlo con un cast!

L’unica ragione per cui un object può chiamare super.foo() per sé è abilitare una chiamata ad essere implementata usando l’implementazione genitore. È compito del codice della class assicurarsi che lo faccia sempre in modo sensato. Ancora una volta, per prendere l’esempio di add-in-a-collection, se la collezione esegue l’override, add un modo per aggiungere l’elemento validato alla raccolta, cosa che farebbe con super.add() .

Si noti che per lo stesso motivo di encapuslation, è ansible chiamare solo l’implementazione genitore, non l’implementazione grandparent – quindi super.foo() è valido, ma super.super.foo() non lo è.

1:

La tua domanda non è abbastanza chiara. Cosa intendi con “call through in runtime come il codice”? Se ti stai chiedendo in che modo l’istanza c sa qual è la sua super class, allora sì, la gerarchia delle classi è memorizzata e può essere letta dalla VM.

2:

Java in realtà ti permette di trasmettere un’istanza al suo genitore. È solo che chiamare un metodo su un’istanza usa sempre la class effettiva dell’istanza, non la sua class di compilazione. Cioè in Java tutti i metodi sono quelli che verrebbero chiamati “virtuali” in C ++. Perché questo è stato deciso non lo so.

Modifica: In realtà Jon Skeet spiega molto bene perché non è ansible chiamare un metodo di una super class su un’istanza di una sottoclass, quindi ora so :-).

È ansible definire un nuovo metodo di supporto nella sottoclass in modo da non sovrascrivere l’originale – chiamarlo – può chiamare il metodo super o meno, a seconda di ciò che si desidera.

In realtà puoi, ma devi usare una metodologia, quindi funzionerà solo sul tuo codice.
Alla super class, aggiungi il parametro “Class” al metodo, come in:

 public String sayColor(Class classFilter){... 

ora, ad ogni override, controlli se la sottoclass corrente è quella del filtro specificato come:

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

Ho codificato in modo esclusivo. Puoi aggiungere più parametri o confrontare con null, in modo da poter unire i risultati con le super classi, usare la tua creatività 🙂