Java può chiamare il metodo ignorato parent in altri oggetti ma non nel sottotipo?

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

  •  06-07-2019
  •  | 
  •  

Domanda

qui funziona 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());
    }
}

ed esecuzione delle stampe della classe Test

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

domanda 1: In fase di esecuzione, il tipo di oggetto C è MyTCup, ma può sempre chiamare il metodo super. Esiste uno stack di metodi in memoria all'interno di MyTCup dopo l'inizializzazione dell'oggetto e quindi può essere richiamato in fase di esecuzione come il codice?

domanda 2: Non è possibile chiamare il metodo super in altri oggetti. Come so, c ++ può eseguire il cast per chiamare il metodo parent in qualsiasi momento. Perché è diverso in Java?

È stato utile?

Soluzione

Non puoi chiamare il metodo super in altri oggetti, il che violerebbe l'incapsulamento. Il punto è che l'oggetto controlla cosa fanno i suoi metodi di override. Ad esempio, potresti ignorare il metodo add di una raccolta per generare un'eccezione in determinate circostanze, in modo da garantire solo " valido " gli articoli sono stati aggiunti alla collezione. Sarebbe inutile se i chiamanti potessero semplicemente aggirarlo con un cast!

L'unico motivo per cui un oggetto può chiamare super.foo () per sé è quello di consentire l'implementazione di una chiamata usando l'implementazione padre. Spetta al codice della classe assicurarsi che lo faccia sempre in modo sensato. Ancora una volta, per prendere l'esempio del componente aggiuntivo in una raccolta, se la raccolta ha la precedenza su aggiungi dovrebbe avere qualche modo di aggiungere l'elemento convalidato alla raccolta, che farebbe con super.add () .

Nota che per lo stesso motivo di incapsulamento, puoi solo chiamare l'implementazione del tuo genitore, non l'implementazione del nonno - quindi super.foo () è valido, ma < codice> super.super.foo () non è.

Altri suggerimenti

1:

La tua domanda non è del tutto chiara. Che cosa intendi con "quot in fase di esecuzione come il codice"? Se stai chiedendo come l'istanza c sappia quale sia la sua superclasse, allora sì, la gerarchia delle classi è archiviata in memoria e può essere raggiunta dalla VM.

2:

Java in realtà ti consente di trasmettere un'istanza al suo genitore. È solo che chiamare un metodo su un'istanza usa sempre la classe effettiva dell'istanza, non la sua classe 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 puoi chiamare un metodo di una super classe su un'istanza di una sottoclasse, quindi ora so :-).

Puoi definire un nuovo metodo di supporto nella sottoclasse in modo da non sovrascrivere l'originale - chiamalo - può chiamare o meno il metodo super, a seconda di ciò che desideri.

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

public String sayColor(Class classFilter){...

ora, ad ogni override, controlli per vedere se la sottoclasse 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à :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top