downcasting en Java + llamando al método con argumentos variables

Mukund Banco:

Cuando llamo a.displayName("Test"), se llama al método de helado de clase. displayName(String...s)método toma en argumentos variables. Salida-

test Icecream
test Faloodeh 
test Faloodeh:  Faloodeh
test Faloodeh:  Faloodeh

Pero cuando cambio el método de displayName(String s)(He comentado que el artículo en el código), entonces se llama al método de la clase faloodeh. nueva output-

test Faloodeh 
test Faloodeh 
test Faloodeh:  Faloodeh
test Faloodeh:  Faloodeh

Yo quería saber por qué ocurre esto.

class Icecream{
    public void displayName(String...s){
        System.out.println(s[0]+" "+"Icecream");
    }
    /*public void displayName(String s){
        System.out.println(s+" "+"Icecream");
    }
    */
    public void describe(String s) {
        System.out.println(s+" "+"Icecream: Ice cream");
    }
}
class Faloodeh extends Icecream {
    public void displayName (String s){
        System.out.println(s+" "+"Faloodeh ");
    }

    public void describe (String s) {
        System.out.println(s+" "+"Faloodeh:  Faloodeh");
    }
}
 class Test {
    public static void main(String arg[]) {
       Icecream a=new Faloodeh ();
       Faloodeh b=( Faloodeh)a;
        a.displayName("test");
        b.displayName("test");
        a.describe("test");
        b.describe("test");
    }
}

** ** Editar- Gracias por las respuestas. Por favor, ayúdame con otra duda. He cambiado el código para -

class Icecream{
    public void displayName(String s){
        System.out.println(s+" "+"Icecream");
    }
    /*public void displayName(String s){
        System.out.println(s+" "+"Icecream");
    }
    */
    public void describe(String s) {
        System.out.println(s+" "+"Icecream: Ice cream");
    }
}
class Faloodeh extends Icecream {
    public void displayName (String...s){
        System.out.println(s+" "+"Faloodeh ");
    }

    public void describe (String s) {
        System.out.println(s+" "+"Faloodeh:  Faloodeh");
    }
}
 class Test {
    public static void main(String arg[]) {
       Icecream a=new Faloodeh ();
       Faloodeh b=( Faloodeh)a;
        a.displayName("test");
        b.displayName("test");
        a.describe("test");
        b.describe("test");
    }
}

Ahora bien, esto da la siguiente output-

test Icecream
test Icecream
test Faloodeh:  Faloodeh
test Faloodeh:  Faloodeh

Como todos ustedes explicado, aquí b es un objeto de la clase faloodeh. Y displayName(String...s)de la clase faloodeh no consigue anulación. Todavía en la salida, se muestra test Icecream¿Por qué?

barredora:

El punto clave aquí es que el cambio displayName(String... s)de displayName(String s)las causas del displayName(String s)método en el Faloodehque anula el método de su superclase.

Icecream.displayName(String... s)y Faloodeh.displayName(String s)tener diferentes firmas, para que no se anulan entre sí. Pero el cambio de la primera a aceptar un Stringsolo les hace tener la misma firma, que causa primordial que se produzca.

En Java, las llamadas a métodos se resuelven en aproximadamente tres pasos (para más información: JLS §15.12 , también he explicado con más detalle aquí ):

  1. Encuentra la clase a buscar métodos aplicables. Esto se basa en el tipo de tiempo de compilación del objeto sobre el que está llamando el método. En este caso, a. a's compilación tipo de tiempo es Icecream, por lo que sólo Icecream' se considerarán s métodos. Tenga en cuenta que no encuentra el displayNamemétodo Faloodehporque el tipo de tiempo de compilación aes Icecream.
  2. Determinar qué sobrecarga del método a llamar sobre la base de los argumentos que ha pasado. Sólo hay una opción aquí. Como antes y después del cambio, displayNamees la única sobrecarga que es compatible con los argumentos que ha pasado.
  3. Determinar qué aplicación del método a la llamada en función del tipo de tiempo de ejecución del objeto sobre el que llamó al método. a's Tipo de tiempo de ejecución es Faloodeh. Antes del cambio, displayNameno se reemplaza en Faloodeh, por lo que llama a la implementación de la superclase. Después del cambio, displayNamese convierte anulado, por lo que la aplicación de Faloodehque se llama.

Con respecto a su edición:

En este caso, ya que el tipo de tiempo de compilación de bes Faloodeh, la clase a buscar es Faloodeh(Paso 1). Sin embargo, hay 2 métodos que coincide con los argumentos que dio (paso 2):

  • displayName(String...)que se declara en Faloodeh, y;
  • displayName(String) que se hereda.

En una situación de este tipo, el compilador siempre favorece la sobrecarga sin aridad variables - displayName(String). Esto se especifica claramente en JLS §15.12.2 . En particular, la etapa 2 es dividen además en tres más sub-pasos. Los primeros intentos sub-paso para encontrar un método sin permitir métodos Arity variables, y si cualquier sub-paso encuentra cualquier método, se omiten los sub-pasos restantes.

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=410054&siteId=1
Recomendado
Clasificación