Durante una de mis entrevistas, me preguntaron "¿Si podemos crear una instancia de una clase abstracta?"
Mi respuesta fue "No. no podemos". Pero, el entrevistador me dijo "Mal, podemos".
Discutí un poco sobre esto. Luego me dijo que probara esto yo mismo en casa.
abstract class my {
public void mymethod() {
System.out.print("Abstract");
}
}
class poly {
public static void main(String a[]) {
my m = new my() {};
m.mymethod();
}
}
Aquí, estoy creando una instancia de mi clase y llamando al método de la clase abstracta. ¿Alguien puede explicarme esto? ¿Estaba realmente equivocado durante mi entrevista?
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.Respuestas:
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 : -
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í:
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:
Poly.java:
Ahora, compila ambos archivos fuente:
Ahora en el directorio donde compiló el código fuente, verá los siguientes archivos de clase:
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: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:
Esos números denotan el orden en que esas clases anónimas aparecen en la clase adjunta.
fuente
instance of
yinstantiating
. Solo crea una instancia de una clase, mientras que el objeto que crea puede ser una instancia de varias clases debido a la herencia.Lo anterior crea una instancia de una clase interna anónima que es una subclase de la
my
clase abstracta. No es estrictamente equivalente a crear instancias de la clase abstracta en sí. OTOH, cada instancia de subclase es una instancia de todas sus superclases e interfaces, por lo que la mayoría de las clases abstractas se instancian al instanciar una de sus subclases concretas.Si el entrevistador acaba de decir "¡mal!" sin dar explicaciones, y dado este ejemplo, como un contraejemplo único, creo que no sabe de qué está hablando.
fuente
subclassInstance instanceof SuperClass
devolvería verdadero, por lo que el objeto es una instancia de la superclase, lo que significa que la superclase ha sido instanciada. Pero eso es solo un punto de mira semántico.= my() {};
significa que hay una implementación anónima, no es simple ejecución de un objeto, que debería haber sido:= my()
. Nunca se puede crear una instancia de una clase abstracta.fuente
Solo observaciones que podrías hacer:
poly
extiendemy
? Esto es inútil ...my.class
,poly.class
ypoly$1.class
¿Podemos instanciar una clase abstracta?
No, no podemos Lo que podemos hacer es crear una clase anónima (ese es el tercer archivo) e instanciarla.
¿Qué pasa con una instanciación de súper clase?
La superclase abstracta no es instanciada por nosotros sino por Java.
EDITAR: Pídele que pruebe esto
la salida es:
fuente
Serializable s = new Serializable() {};
(que es bastante inútil) y si está etiquetado en su código daríaclass my$3
(o cualquier clase y número adjunto)Simplemente puede responder, en una sola línea.
Pero, el entrevistador todavía no está de acuerdo, entonces puede decirle
Y, de acuerdo con la clase anónima, clase declarada e instanciada en el mismo lugar / línea
Por lo tanto, es posible que el entrevistador esté interesado en verificar su nivel de confianza y cuánto sabe acerca de los POO.
fuente
La parte técnica ha sido bien cubierta en las otras respuestas, y termina principalmente en:
"Está equivocado, no sabe nada, pídale que se una a SO y que todo se aclare :)"
Me gustaría abordar el hecho (que se ha mencionado en otras respuestas) de que esta podría ser una pregunta de estrés y es una herramienta importante para que muchos entrevistadores sepan más sobre usted y cómo reacciona ante situaciones difíciles e inusuales. Al darte códigos incorrectos, probablemente quería ver si respondías. Para saber si tiene la confianza para enfrentarse a sus mayores en situaciones similares a esta.
PD: No sé por qué, pero tengo la sensación de que el entrevistador ha leído esta publicación.
fuente
Las clases abstractas no pueden instanciarse, pero pueden subclasificarse. Ver este enlace
El mejor ejemplo es
Aunque la clase Calender tiene un método abstracto getInstance () , pero cuando dices
Calendar calc=Calendar.getInstance();
calc se refiere a la instancia de clase de la clase GregorianCalendar como "GregorianCalendar extiende Calendario "
De hecho, el tipo interno anónimo le permite crear una subclase sin nombre de la clase abstracta y una instancia de esta.
fuente
Respuesta técnica
Las clases abstractas no se pueden instanciar, esto es por definición y diseño.
Del JLS, Capítulo 8. Clases:
Desde JSE 6 java doc para Classes.newInstance ():
Por supuesto, puede crear una instancia de una subclase concreta de una clase abstracta (incluida una subclase anónima) y también realizar una conversión de tipo de una referencia de objeto a un tipo abstracto.
Un ángulo diferente sobre esto - Teamplay e inteligencia social:
Este tipo de malentendido técnico ocurre con frecuencia en el mundo real cuando tratamos con tecnologías complejas y especificaciones legalistas.
Las "habilidades de la gente" pueden ser más importantes aquí que las "habilidades técnicas". Si intenta probar su lado del argumento de manera competitiva y agresiva, entonces podría tener razón teóricamente, pero también podría hacer más daño al tener una pelea / "cara" dañina / crear un enemigo de lo que vale. Sea reconciliador y comprensivo para resolver sus diferencias. ¿Quién sabe, tal vez tienes "la razón" pero estás trabajando con significados ligeramente diferentes para los términos?
Quién sabe, aunque no es probable, es posible que el entrevistador haya introducido deliberadamente un pequeño conflicto / malentendido para ponerlo en una situación desafiante y ver cómo se comporta emocional y socialmente. Sea amable y constructivo con sus colegas, siga los consejos de las personas mayores y realice un seguimiento después de la entrevista para resolver cualquier desafío / malentendido, por correo electrónico o llamada telefónica. Muestra que estás motivado y orientado a los detalles.
fuente
Es un hecho bien establecido que no
abstract class
puede ser instanciado como todos respondieron.Cuando el programa define una clase anónima, el compilador crea una nueva clase con un nombre diferente (tiene el patrón
EnclosedClassName$n
donden
está el número de clase anónima)Entonces, si descompila esta clase de Java, encontrará el código de la siguiente manera:
mi clase
poly $ 1.class (la clase generada de la "clase anónima")
ploly.cass
fuente
No, no puede crear una instancia de una clase abstracta. Instanciamos solo clases anónimas. En la clase abstracta declaramos métodos abstractos y definimos solo métodos concretos.
fuente
Sobre clases abstractas
El propósito de una clase abstracta es comportarse como una base. En la jerarquía de herencia verá clases abstractas hacia la parte superior.
fuente
Puede decir:
no podemos crear una instancia de una clase abstracta, pero podemos usar
new
palabras clave para crear una instancia de clase anónima simplemente agregando{}
como cuerpo de implementación al final de la clase abstracta.fuente
Extender una clase no significa que está creando una instancia de la clase. En realidad, en su caso está creando una instancia de la subclase.
Estoy bastante seguro de que las clases abstractas no permiten iniciar. Entonces, diría que no: no se puede crear una instancia de una clase abstracta. Pero, puedes extenderlo / heredarlo.
No se puede crear una instancia directa de una clase abstracta. Pero no significa que no pueda obtener una instancia de clase (no realmente una instancia de clase abstracta original) indirectamente. Quiero decir que no puedes crear una instancia de la clase abstracta original, pero puedes:
Por lo tanto, obtiene acceso a todos los métodos y propiedades en una clase abstracta a través de la instancia de clase derivada.
fuente
Es imposible instanciar una clase abstracta. Lo que realmente puede hacer es implementar algunos métodos comunes en una clase abstracta y dejar que otros no se implementen (declarándolos abstractos) y dejar que el descendiente concreto los implemente según sus necesidades. Luego puede hacer una fábrica, que devuelve una instancia de esta clase abstracta (en realidad su implementador). En la fábrica, usted decide qué implementador elegir. Esto se conoce como un patrón de diseño de fábrica:
El implementador concreto solo necesita implementar los métodos declarados como abstractos, pero tendrá acceso a la lógica implementada en esas clases en una clase abstracta, que no se declaran abstractas:
Entonces, finalmente, la fábrica se ve así:
El receptor de AbstractGridManager invocaría los métodos en él y obtendría la lógica, implementada en el descendiente concreto (y parcialmente en los métodos de la clase abstracta) sin saber cuál es la implementación concreta que obtuvo. Esto también se conoce como inversión de control o inyección de dependencia.
fuente
No, no podemos crear el objeto de la clase abstracta, sino crear la variable de referencia de la clase abstracta. La variable de referencia se utiliza para referirse a los objetos de las clases derivadas (subclases de la clase abstracta)
Aquí está el ejemplo que ilustra este concepto.
Aquí vemos que no podemos crear el objeto de tipo Figura pero podemos crear una variable de referencia de tipo Figura. Aquí creamos una variable de referencia del tipo Figura y Figura La variable de referencia Clase se usa para referirse a los objetos de Clase Rectángulo y Triángulo.
fuente
En realidad, no podemos crear un objeto de una clase abstracta directamente. Lo que creamos es una variable de referencia de una llamada abstracta. La variable de referencia se utiliza para referirse al objeto de la clase que hereda la clase abstracta, es decir, la subclase de la clase abstracta.
fuente