inicialización de objetos - La relación del constructor para el tipo de clase y acceso método

Phoenix:

Tengo el siguiente código:

package testapp;

class Calculation {

    public Calculation(){}

    public void addition(int x, int y) {   }

    public void Subtraction(int x, int y) {   }
}

class My_Calculation extends Calculation {

    public My_Calculation(){}

    public void multiplication(int x, int y) {   }
}

public class TestApp {

    public static void main(String[] args) {

        int a = 20, b = 10;

        My_Calculation demo = new My_Calculation();
        demo.addition(a, b);
        demo.Subtraction(a, b);
        demo.multiplication(a, b);
        System.out.println(demo.getClass().getName());

        Calculation d = new Calculation();
        d.Subtraction(b, b);
        d.addition(b, b);
        // no multiplication
        System.out.println(d.getClass().getName());

        Calculation d2 = new My_Calculation();
        d2.Subtraction(b, b);
        d2.addition(b, b);
        // no multiplication
        System.out.println(d2.getClass().getName());
    } 
}

La salida es la siguiente:

Demo = testapp.My_Calculation

d = testapp.Calculation

d2 = testapp.My_Calculation

La siguiente declaración es una declaración de que el nombre variable de referencias d2 de tipo de objeto de cálculo :

Calculation d2;

La siguiente declaración es una inicialización que llama constructor My_Calculation.

Calculation d2 = new My_Calculation();

Cuando ejecuto el siguiente código, la salida indica que d2 es del tipo de clase My_Calculation sino que da acceso a los métodos dentro de la clase de cálculo .

System.out.println(d2.getClass().getName());

Salida: testapp.My_Calculation

Acceso: adición; sustracción

Ahora, mi entendimiento me dice que si My_Calculation se llama al constructor que debería tener ya sea:

1. Acceso a exclusivamente a la reproducción, o

2. Acceso a la suma, resta y multiplicación.

Pero, de hecho me da la inversa: el acceso a la suma y la resta SOLAMENTE . Por lo tanto, veo esto como contrario a la intuición.

Podría alguien explicarme lo que está sucediendo aquí para dar una comprensión coherente de por qué un objeto de tipo: My_Calculation no tendría acceso a sus propios métodos , pero el acceso a sólo los métodos superclases .

GhostCat saludos Monica C.:

Aquí:

Calculation d2 = new My_Calculation();

Se crea un objeto de tipo My_Calculation, pero que se le asigna a una variable declarada con el supertipo! Y el compilador no es lo suficientemente inteligente como para "ver" que d2es en realidad el tipo de niño. Así, los compiladores le impide llamar a un método definido en ese tipo de niños. Debido a que el compilador, d2se sabe que es una Calculation!

Tenga en cuenta que se puede echar a decirle al compilador "Yo sé mejor":

( (My_Calculation) d2) ).multiplication(...

que trabajaría en tiempo de compilación, y también en tiempo de ejecución!

Su idea errónea comienza aquí:

Calculation d2 = new My_Calculation();

Lo que se hace en el lado derecho de la asignación es básicamente "olvidado" en la siguiente línea. A continuación, el compilador sólo se sabe que tiene algún d2tipo Calculation!

Por último: si, en su específica ejemplo, el compilador podría fácilmente determinar el verdadero tipo de d2. Sin embargo, hay muchas situaciones en las que no es fácil, o incluso imposible. Por lo tanto las personas que están detrás de Java decidieron ignorar tales "conocimiento" potencial.

Supongo que te gusta

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