¿Crear una clase abstracta de Java?
instantiation urlconnection (6)
Esta pregunta ya tiene una respuesta aquí:
- ¿Qué significa "programar a una interfaz"? 32 respuestas
Relativamente nuevo programador de Java y me han enseñado que no se puede crear una instancia de una clase abstracta. También he investigado un poco y aprendí que en la mayoría de los casos, cuando aparece una clase abstracta, en realidad es una subclase anónima. Pero aquí está el problema que me encontré:
La clase de URL
de Java tiene un método openConnection
que devuelve un URLConnection
. URLConnection
es una clase abstracta, y la documentación de Java también enumera todas sus subclases como resumen ... así que estoy realmente perdido. ¿Qué está siendo devuelto?
Podria ser anonima clase
Digamos que tienes una abstract class
...
abstract class Vehicle {
abstract public void move();
}
Sin hacer una class Car extends Vehicle
un class Car extends Vehicle
o una class Boat extends Vehicle
, puedes hacer esto con la magia de las clases anónimas. (Esta puede ser la razón por la cual el javadoc no dice que hay una subclase porque es anónima y, por lo tanto, no puede hacer referencia a la API pública, que representa el javadoc).
class Example {
public Vehicle foo() {
Vehicle car = new Vehicle {
@Override
public void move() {
// do some car movement, i.e. driving
}
}
return car;
}
public Vehicle bar() {
Vehicle boat = new Vehicle {
@Override
public void move() {
// do some boat movement, i.e. boating
}
}
return boat;
}
}
Así que no, no puede crear una instancia de una abstract class
... pero esa no es realmente la verdad, puede hacerlo como una Clase Anónima e implementar los métodos en el momento. Sin embargo, esto técnicamente no es una abstract class
, pero es lo que se hace mucho cuando se ve este tipo de cosas.
Podría ser privado Clase Interna
Una vez más, digamos que tienes una abstract class
...
abstract class Vehicle {
abstract public void move();
}
Si la class
interna era private
, solo la clase que la encierra puede ejemplificarla. (Lo que puede ser la razón por la cual el javadoc no dice que hay una subclase porque es privada y, por lo tanto, está oculta de la API pública, que representa el javadoc).
class Example {
private class Car extends Vehicle {
@Override
public void move() {
// do some car movement, i.e. driving
}
}
private class Boat extends Vehicle {
@Override
public void move() {
// do some boat movement, i.e. boating
}
}
public Vehicle foo() {
return new Car();
}
public Vehicle bar() {
return new Boat();
}
}
Esto no explica nada sobre la creación de instancias de abstract class
, pero puede ayudar a responder sobre URL
, openConnection
y URLConnection
.
Cuando todas las subclases son abstractas, es porque solo se pueden usar las clases al crearlas en una fábrica. Si verifica cuidadosamente el código en Uso de java.net.URLConnection para disparar y manejar solicitudes HTTP , verá que el objeto URLConnection
nunca se URLConnection
instancia. En su lugar, lo conseguimos llamando a openConnection
esta manera:
URLConnection connection = new URL(url + "?" + query).openConnection();
El concepto de polimorfismo se aplicará aquí.
El tipo de objetos será URLConnection (clase principal / interfaz) y el objeto será de su clase secundaria (amplia o implementa (en caso de interfaz)).
El siguiente ejemplo podría aclarar esto.
abstract class URLConnection {
// some methods.
}
Supongamos que tienes tu propia clase.
class ConnectionClass extends URLConnection {
// some methods
}
class Main {
URLConnection connect = null
public URLConnection getUrl() {
return connect = new ConnectionClass();
}
}
openConnection()
objeto de la clase, quien otorga la implementación de openConnection()
de la clase URLConnection
. Los mismos conceptos se aplican en caso de interfaz.
Es una clase que extiende URLConnection
que se está devolviendo. Es una forma de ocultar los detalles de la implementación, URLConnection
se pueden devolver diferentes implementaciones de URLConnection
en función de los parámetros de entrada.
Lo que se devuelve es una subclase no abstracta que no encontrará en la documentación de la API, por ejemplo sun.net.www.protocol.http.HttpUrlConnection
. Si ejecuta el mismo código desde un applet en un navegador, es probable que obtenga uno diferente, generalmente algo que envuelve las conexiones nativas del navegador.
Así que no hay truco ni magia allí, solo que algunas clases no aparecen en los documentos API, ya que se consideran internas a la implementación y están sujetas a cambios.
Hay muchos ejemplos similares, DocumentBuilderFactory
o TransformerFactory
son abstractos, pero su método newInstance()
devolverá una subclase, generalmente empaquetada por separado (por ejemplo, Saxon ).
Pero también hay diferentes soluciones para el mismo problema: JDBC define la interfaz del Driver
(en lugar de una clase abstracta) y una clase de utilidad DriverManager
con métodos estáticos para cargar las diferentes implementaciones del controlador. En lugar de extender una clase abstracta, los proveedores de controladores de base de datos deben implementar la interfaz del Driver
.
Por cierto, para encontrar la clase de tiempo de ejecución real del objeto, simplemente llame a getClass()
en ellos.
openConnection
devuelve alguna clase concreta que extiende URLConnection
. La firma del método se define como la devolución de URLConnection
ya que su código que lo usa no debe basarse en ninguna implementación específica.