2011-07-22 15 views
6

Perché System.out.println(super) non è consentito?Perché System.out.println (super) non è consentito?

System.out.println(this); 

Questo è OK e this.toString() si chiama e stampato automaticamente. Ovviamente, la variabile di istanza è OK invece di this.

Tuttavia, this e super possono essere utilizzati nello stesso modo che conosco.

System.out.println(super); 

Quindi, perché questo non funziona? Penso che dovrebbe chiamare lo super.toString() implicitamente. Ho letto il documento delle specifiche Java, ma non ne ho trovato il motivo.

+2

Come fallisce? È un errore di compilazione? Un'eccezione di runtime? o comportamento inaspettato? (ad es. 'System.out.println (super)' stampa la stessa cosa di 'this.toString()') –

+0

Il problema è che si è verificato un errore di compilazione dal secondo caso usando 'super'. Il messaggio di errore è "'." previsto "e sembra un errore di sintassi. – JaycePark

+0

* "È una domanda semplice." * Si noti che "Qual è il significato della vita?" è una domanda semplice È la risposta più difficile. ;) –

risposta

4

Attuare una variante autonoma di super che rompe metodo invio virtuale sarebbe una pessima idea.

Pensiamoci per un po '.

abstract class Base { 
    abstract String Description(); 
    String toString() { return "Base"; } 
} 
class Derived extends Base { 
    String Description() { return "Derived description"; } 
    String toString() { return "Derived"; } 

    static void use(Base instance) { 
     System.out.println(instance.toString()); 
     System.out.println(instance.Description()); 
    } 
} 

Ora, prendiamo il vostro suggerimento e supponiamo che super sia valido e che quello che suggeriscono; allora possiamo scrivere in Derived:

class Derived extends Base { 
    // Previous declarations omitted. 
    void useSuper() { Derived.use(super); } 
    void useThis() { Derived.use(this); } 

    static void main() { 
     Derived instance = new Derived(); 
     instance.useThis(); 
     instance.useSuper(); 
    } 
} 

Ora, se ho capito, si suggeriscono che la funzione principale dovrebbe stampare in ordine:

  • l'attuazione di toString() da Derived: "derivata".
  • l'attuazione di Description() da Derived: "Descrizione derivata"
  • l'attuazione di toString() da Base: "Base".
  • l'implementazione di Description() da Base: Non esiste. E le due soluzioni che posso pensare portano a problemi più grandi:
    • Sollevare un'eccezione: congratulazioni, ora puoi interrompere qualsiasi programma che si basa su metodi astratti effettivamente implementati senza nemmeno pensarci. (Come sapresti che una funzione chiamerà il metodo astratto?)
    • Restituisci l'implementazione da Derived: interruzione della coerenza.

In breve, un tale uso della parola super rompe concettualmente programmazione orientata agli oggetti.

+0

Grazie, penso che la tua risposta sia molto chiara basata su OOP. – JaycePark

8

controlla la grammatica in http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html

I super parole chiave devono essere sempre seguiti da SuperSuffix, che non può essere vuoto.

Quindi super non può mai stare da solo come espressione.

+0

per un secondo pensavo fosse possibile, così mi è stato scritto un piccolo programma per testarlo: S –

0

this si riferisce al tuo attuale oggetto . super fa riferimento alla classe super , la classe da cui l'oggetto corrente eredita direttamente (o può essere il costruttore del super). Così

System.out.println(this) 

stamperà metodo toString() del vostro oggetto, ma

System.out.println(super) 

fallisce perché super-non è un oggetto (e quindi non ha un metodo toString()).

+2

Per chiarire ulteriormente, 'super' si riferisce a una classe, che ha un metodo toString(), ma il metodo non è statico ; non può essere invocato a livello di classe. Ha bisogno di essere chiamato su un oggetto, come "questo". – Steven

+0

Se ci pensi, anche se super era un oggetto, sarebbe lo stesso oggetto di questo. –

+0

@StevenNoto, se super si riferisce a una classe e che non ha un metodo toString() statico, allora come funziona questo codice 'System.out.println (super.toString());' funziona? –

-5

Super è rilevante solo per la chiamata di metodi statici. Se si chiama il metodo non statico usando super che in realtà si riferisce al proprio oggetto, ad esempio this. Ad esempio, puoi dire System.out.println(super.toString()). Questo funzionerà e verrà eseguito il toString() della classe effettiva.

Penso che questo sia il motivo per cui è vietato passare super come argomento ad un altro metodo.

+0

No, anche il metodo non statico con super funziona. toString non è un metodo statico e chiamare super.toString() chiamerà correttamente toString() della classe antenata. – Raze

+0

Ho detto che funziona. Ma chiama il toString() della classe reale, non la sua super classe! – AlexR

+3

Abbastanza sicuro che sia falso. Potresti voler testare questo su classi semplici, l'ho fatto e ho capito che si chiama metodo della super classe. – Jodaka

Problemi correlati