¿Crear una clase abstracta de Java?




instantiation urlconnection (4)

Esta pregunta ya tiene una respuesta aquí:

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();

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.





urlconnection