2011-07-22 18 views
6

¿Por qué no se permite System.out.println(super)?¿Por qué no se permite System.out.println (super)?

System.out.println(this); 

Esto está bien y this.toString() se llama y se imprime automáticamente. Por supuesto, la variable de instancia está OK en lugar de this. Sin embargo, this y super se pueden usar de la forma que yo sé.

System.out.println(super); 

¿Por qué no funciona esto? Creo que se supone que debe llamar al super.toString() implícitamente. He leído el documento de especificación de Java, pero no he encontrado el motivo.

+2

¿Cómo falla? ¿Es un error de compilación? Una excepción de tiempo de ejecución? o comportamiento inesperado? (por ejemplo, 'System.out.println (super)' imprime lo mismo que 'this.toString()') –

+0

El problema es que se produjo un error de compilación en el segundo caso con 'super'. El mensaje de error es "'.' esperado "y parece un error de sintaxis. – JaycePark

+0

* "Es una pregunta simple." * Tenga en cuenta que "¿Cuál es el significado de la vida?" es una pregunta simple Es la respuesta que es más difícil. ;) –

Respuesta

4

La implementación de una variante independiente de super que rompe método virtual de despacho sería una muy mala idea.

Vamos a pensar en ello durante un tiempo.

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

Ahora, tomemos su sugerencia y suponemos que super es válido y hace lo que usted sugiere; entonces podemos escribir en 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(); 
    } 
} 

Ahora, si le he entendido, que sugieren que la función principal debe imprimir en orden:

  • la implementación de toString() de Derived: "Derivado".
  • la implementación de Description() de Derived: "Descripción Derivado"
  • la implementación de toString() de Base: "Base".
  • la implementación de Description() de Base: No existe. Y las dos soluciones que puedo pensar conducen a problemas mayores:
    • Eleve una excepción: enhorabuena, ahora puede romper cualquier programa que dependa de métodos abstractos realmente implementados sin siquiera pensar en ello. (¿Cómo sabría que una función llamará al método abstracto?)
    • Devuelva la implementación de Derived: rompe la coherencia.

En definitiva, un uso de la palabra super tales rompe conceptualmente la programación orientada a objetos.

+0

Gracias, creo que tu respuesta es muy clara en base a OOP. – JaycePark

8

revisar la gramática en http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html

Los super palabras clave siempre deben ser seguidas por SuperSuffix, que no puede estar vacío.

Así super nunca puede estar solo como una expresión.

+0

por un segundo estaba pensando que era posible, así que me escribió un pequeño programa para probarlo: S –

0

this se refiere a su objeto actual. super se refiere a la clase super, la clase que hereda directamente su objeto actual (o puede ser el constructor del super). Así

System.out.println(this) 

imprime método de su objeto toString(), pero

System.out.println(super) 

falla porque súper no es un objeto (y por lo tanto tiene ningún método toString()).

+2

Para aclarar más, 'super' se refiere a una clase, que tiene un método toString(), pero el método no es estático ; no puede ser invocado en el nivel de clase. Necesita ser llamado en un objeto, como 'this'. – Steven

+0

Si lo piensas, incluso si super era un objeto, sería el mismo objeto. –

+0

@StevenNoto, si super se refiere a una clase y no tiene un método static toString(), ¿cómo funciona este código 'System.out.println (super.toString());'? –

-5

Super es relevante para la llamada de métodos estáticos solamente. Si llama al método no estático utilizando super que en realidad es una referencia a su objeto en sí, es decir, al this. Por ejemplo, puede decir System.out.println(super.toString()). Esto funcionará y ejecutará el toString() de la clase real.

Creo que esta es la razón por la que pasa super como argumento para otro método está prohibido.

+0

No, llamar al método no estático usando super también funcionará. toString no es un método estático, y al llamar a super.toString() se llamará correctamente a toString() de la clase ancestra. – Raze

+0

Dije que funciona. ¡Pero llama a toString() de clase real, no a su superclase! – AlexR

+3

Bastante seguro de que es falso. Es posible que desee probar esto en clases simples, lo hice y entendí que se llamaba método de la superclase. – Jodaka

Cuestiones relacionadas