Aquí estoy creando una instancia de mi clase
No, no está creando la instancia de su clase abstracta aquí. Por el contrario, está creando una instancia de una subclase anónima de su clase abstracta. Y luego está invocando el método en su referencia de clase abstracta apuntando al objeto de subclase .
Este comportamiento está claramente listado en JLS - Sección # 15.9.1 : -
Si la expresión de creación de instancia de clase termina en un cuerpo de clase, entonces la clase que se instancia es una clase anónima. Entonces:
- Si T denota una clase, se declara una subclase directa anónima de la clase nombrada por T. Es un error en tiempo de compilación si la clase denotada por T es una clase final.
- Si T denota una interfaz, se declara una subclase anónima directa de Object que implementa la interfaz nombrada por T.
- En cualquier caso, el cuerpo de la subclase es el ClassBody dado en la expresión de creación de instancia de clase.
- La clase que se instancia es la subclase anónima.
El énfasis es mío.
Además, en JLS - Sección # 12.5 , puede leer sobre el Proceso de creación de objetos . Citaré una declaración de eso aquí:
Cada vez que se crea una nueva instancia de clase, se le asigna espacio de memoria con espacio para todas las variables de instancia declaradas en el tipo de clase y todas las variables de instancia declaradas en cada superclase del tipo de clase, incluidas todas las variables de instancia que pueden estar ocultas.
Justo antes de que se devuelva una referencia al objeto recién creado como resultado, el constructor indicado se procesa para inicializar el nuevo objeto mediante el siguiente procedimiento:
Puede leer sobre el procedimiento completo en el enlace que proporcioné.
Para ver prácticamente que la clase que se está instanciando es una Subclase anónima , solo necesita compilar ambas clases. Supongamos que coloca esas clases en dos archivos diferentes:
My.java:
abstract class My {
public void myMethod() {
System.out.print("Abstract");
}
}
Poly.java:
class Poly extends My {
public static void main(String a[]) {
My m = new My() {};
m.myMethod();
}
}
Ahora, compila ambos archivos fuente:
javac My.java Poly.java
Ahora en el directorio donde compiló el código fuente, verá los siguientes archivos de clase:
My.class
Poly$1.class // Class file corresponding to anonymous subclass
Poly.class
Ver esa clase - Poly$1.class
. Es el archivo de clase creado por el compilador correspondiente a la subclase anónima que creó mediante el siguiente código:
new My() {};
Entonces, está claro que hay una clase diferente siendo instanciada. Es solo eso, esa clase recibe un nombre solo después de la compilación por parte del compilador.
En general, todas las subclases anónimas de su clase se nombrarán de esta manera:
Poly$1.class, Poly$2.class, Poly$3.class, ... so on
Esos números denotan el orden en que esas clases anónimas aparecen en la clase adjunta.
B
de una abstractaA
, durante la parte de construcción deB
instancia, que consiste en ejecutarA
el constructor, el tipo de tiempo de ejecución del objeto es en realidadA
. Sin embargo, solo temporal.