2011-05-26 13 views
8

¿Por qué el código siguiente imprime "1"?java covariant return type

class A { 
    int x = 1; 
} 

class B extends A { 
    int x = 2; 
} 

class Base { 

    A getObject() { 
     System.out.println("Base"); 
     return new B(); 
    } 
} 

public class CovariantReturn extends Base { 

B getObject() { 
    System.out.println("CovariantReturn"); 
    return new B(); 
} 
/** 
* @param args 
*/ 
public static void main(String[] args) { 
    Base test = new CovariantReturn(); 
    System.out.println(test.getObject() instanceof B); 
    System.out.println(test.getObject().x); 
} 
} 

Respuesta

13

Porque se refiere a campos que no se ven afectados por el polimorfismo. Si en su lugar usaste getX(), hubiera regresado 2.

Lo que está preguntando es, el valor del campo x definido en la clase A (porque Base.getObject() devuelve A). Aunque CovariantReturn anula el método para devolver B, no se está refiriendo a su objeto como CovariantReturn.

Para ampliar un poco sobre cómo los campos no son afectadas por el polimorfismo - el acceso de campo se realiza en tiempo de compilación, por lo que cualquiera que sea el compilador ve, eso es lo que está accediendo. En su caso, el método define devolver A y así se accede al A.x. Por otro lado, los métodos se invocan en función del tipo de tiempo de ejecución. Por lo tanto, incluso si define devolver A pero devuelve una instancia de B, se invocará el método que invoca en B.

+0

pero estoy regresando nuevo B() – kris979

+0

pero el método para volver define 'A'. Y entonces 'A.x' es a lo que se accede. – Bozho

+1

@kris que está llamando método que utiliza la referencia de 'A' en que tiene thereturn tipo' A' –

0

@ kris979 Aunque va a devolver B, creo que lo que hace la diferencia es que el tipo de retorno es de A. Por lo tanto, el valor de x en A decir 1 se imprime.

0

Como se señaló Bozho - variable de instancia no se ven afectados por el polimorfismo. Déjame darte un pequeño ejemplo rápido.

class Base { 
    int i = 1; 
    void method() { 
     System.out.println("in base"); 
    } 
} 

class Sub extends Base { 
    int i = 2; 

    void method() { 
     System.out.println("in sub"); 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     Base obj = new Sub(); 
     obj.method(); 
     System.out.println(obj.i); 
    } 
} 

Este código imprimirá - en sub y 1

+0

agradable. respuesta simple y ordenada – STEEL