2015-05-01 21 views
16

Relativamente nuovo programmatore Java e mi è stato insegnato che non è possibile creare un'istanza di una classe astratta. Ho anche fatto una piccola ricerca e ho appreso che nella maggior parte dei casi quando appare una classe astratta viene creata, in realtà è una sottoclasse anonima. Ma ecco il problema che ho riscontrato:Istanziata classe astratta Java?

La classe Java URL ha un metodo openConnection che restituisce un URLConnection. URLConnection è una classe astratta, e la documentazione Java elenca anche tutte le sue sottoclassi come abstract ..... quindi sono davvero perso. Cosa viene restituito?

+7

Una sottoclasse di 'URLConnection', proprio come hai detto tu. –

+4

La classe concreta del 'URLConnection' restituito è probabilmente contrassegnata come' private'. –

+0

Dai anche un'occhiata a http://stackoverflow.com/questions/2793150/using-java-net-urlconnection-to-fire-and-handle-http-requests. Il concetto polimorfico – mattias

risposta

2

È una classe che estende URLConnection che viene restituita. È un modo per nascondere i dettagli di implementazione poiché è possibile restituire un'implementazione diversa di URLConnection in base ai parametri di input.

14

openConnection restituisce una classe concreta che estende URLConnection. La firma del metodo è definita come restituendo URLConnection poiché il codice che lo utilizza non dovrebbe fare affidamento su alcuna implementazione specifica.

+3

Tutto in questo la risposta è corretta ma non penso che risponda alla domanda su cosa viene effettivamente restituito. –

11

Il concetto di polimorfismo verrà applicato qui.

Il tipo di oggetti sarà URLConnection (classe padre \ interfaccia) e l'oggetto sarà della classe figlio (estensione o implementazione (in caso di interfaccia)).

L'esempio seguente potrebbe rendere chiara questa cosa.

abstract class URLConnection { 
    // some methods. 
} 

Supponiamo che tu abbia la tua classe.

class ConnectionClass extends URLConnection { 
    // some methods 
} 

class Main { 
    URLConnection connect = null 

    public URLConnection getUrl() { 
    return connect = new ConnectionClass(); 
    } 
} 

Si tornerà oggetto della classe, che dà attuazione openConnection() di URLConnection di classe. Stessi concetti si applicano nel caso dell'interfaccia.

1

Quando tutte le sottoclassi sono astratte, è perché è possibile utilizzare le classi solo creando in una fabbrica. Se si controlla attentamente il codice in Using java.net.URLConnection to fire and handle HTTP requests, si vedrà che l'oggetto URLConnection non viene mai istanziato. Invece, abbiamo capito chiamando openConnection come questo:

URLConnection connection = new URL(url + "?" + query).openConnection(); 
7

Potrebbe essere Anonymous Class

Diciamo che avete un abstract class ...

abstract class Vehicle { 
    abstract public void move(); 
} 

senza mai fare un class Car extends Vehicle o class Boat extends Vehicle si può fare questo con la magia delle classi anonime. (che può essere il motivo per cui il javadoc non dice c'è una sottoclasse perché è anonimo e quindi non può essere riferimento l'API pubblica, quale il javadoc rappresenta.)

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; 
    } 
} 

Così senza si puo' t istanziare un abstract class ... ma non è tutta la verità, puoi farlo come una classe anonima e implementare i metodi sul posto. Questo tecnicamente non sta istanziando un abstract class, ma è quello che viene fatto molto quando vedi questo genere di cose.


potrebbero essere privati ​​Inner Class

Anche in questo caso, dire che avete un abstract class ...

abstract class Vehicle { 
    abstract public void move(); 
} 

Se l'interno class era private allora solo la classe che si incassa potrebbe un'istanza. (che può essere il motivo per cui il javadoc non dice c'è una sottoclasse perché è privata e quindi nascosta al API pubblica, quale il javadoc rappresenta.)

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

Questo non spiega nulla su un'istanza abstract class es, ma può aiutare a rispondere su URL, openConnection e URLConnection.

16

Ciò che viene restituito è una sottoclasse non astratta che non troverete nella documentazione API, ad esempio sun.net.www.protocol.http.HttpUrlConnection. Se esegui lo stesso codice da un'applet in un browser, probabilmente ne otterrai uno diverso, di solito qualcosa che racchiude le connessioni native del browser.

Quindi non c'è alcun trucco e nessuna magia, solo che alcune classi non vengono visualizzate nei documenti API poiché sono considerate interne all'implementazione e soggette a modifiche.

Ci sono molti esempi simili, DocumentBuilderFactory o TransformerFactory sono entrambi astratto, ma il loro metodo newInstance() tornerà una sottoclasse, solitamente confezionati separatamente (ad esempio Saxon).

Ma esistono anche diverse soluzioni per lo stesso problema: JDBC definisce l'interfaccia Driver (anziché una classe astratta) e una classe di utilità DriverManager con metodi statici per caricare le diverse implementazioni del driver. Invece di estendere una classe astratta, i fornitori di driver di database sono tenuti ad implementare l'interfaccia Driver.

A proposito, per trovare la classe di esecuzione effettiva dell'oggetto, è sufficiente chiamare getClass() su di essi.

+0

[Questa risposta] (http://stackoverflow.com/a/1834836/1858327) da un'altra domanda spiega ulteriormente perché queste classi non sono presenti nella documentazione. –

Problemi correlati