2015-05-01 201 views
16

相對較新的Java程序員,我被教導你不能創建一個抽象類的實例。我也做了一些小小的研究,我發現在大多數情況下,當它出現一個抽象類時,它實際上是一個匿名的子類。但這是我碰到的問題:實例化Java抽象類?

Java的URL類有一個方法openConnection返回URLConnectionURLConnection是一個抽象類,Java文檔也列出了它的所有子類作爲抽象.....所以我真的迷失了。什麼是返回?

+7

「URLConnection」的一個子類,就像你說的。 –

+4

返回的'URLConnection'的具體類可能被標記爲'private'。 –

+0

也看看http://stackoverflow.com/questions/2793150/using-java-net-urlconnection-to-fire-and-handle-http-requests。 – mattias

回答

2

這是繼續返回的類URLConnection。這是一種隱藏實現細節的方法,因爲可以根據輸入參數返回URLConnection的不同實現。

14

openConnection返回一些延伸URLConnection的具體類。該方法的簽名定義爲返回URLConnection,因爲使用它的代碼不應該依賴任何特定的實現。

+3

答案是正確的,但我不認爲它回答了什麼是實際返回的問題。 –

11

多態概念適用於此。

對象的類型將是URLConnection(Parent class \ interface),並且對象將是其子類(擴展或實現(在接口的情況下))。

下面的例子可能會讓你明白這件事。

abstract class URLConnection { 
    // some methods. 
} 

讓我們假設你有自己的班級。

class ConnectionClass extends URLConnection { 
    // some methods 
} 

class Main { 
    URLConnection connect = null 

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

您將返回類,誰給的實施URLConnectionopenConnection()的對象。相同的概念適用於界面的情況。

1

當所有的子類都是抽象的,那是因爲你只能通過在工廠中創建它來使用類。如果您仔細檢查Using java.net.URLConnection to fire and handle HTTP requests中的代碼,您將看到URLConnection對象從未實例化過。取而代之的是,我們得到它通過調用openConnection這樣的:

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

可能是Anonymous Class

假設你有一個abstract class ...

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

而沒有作出class Car extends Vehicleclass Boat extends Vehicle你可以做這與匿名類的魔力。 (這或許就是javadoc的不說還有一個子類,因爲它是匿名的,因此不能由公共API,它的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; 
    } 
} 

所以沒有你可以」 t實例化一個abstract class ......但這並不是真正的全部事實,你可以將它作爲一個匿名類來實現,並且可以實現這些方法。儘管這在技術上並不是實例化的,但是當你看到這種事情時,它會得到很多。


可以是私營Inner Class

再次,說你有一個abstract class ...

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

如果內classprivate那麼只有被包圍它可以初始化它的類。 (這或許就是javadoc的不說還有一個子類,因爲它是私有的,因此從公共API,它的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(); 
    } 
} 

這並不能說明有關實例abstract class什麼但它可能有助於回答約URL,openConnectionURLConnection

16

返回的內容是您在API文檔中找不到的非抽象子類,例如sun.net.www.protocol.http.HttpUrlConnection。如果您在瀏覽器中從applet運行相同的代碼,您可能會得到不同的代碼,通常是包裝瀏覽器本地連接的東西。

因此,這裏沒有任何技巧也沒有什麼魔法,只是有些類不會顯示在API文檔中,因爲它們被認爲是實現的內部特徵,可能會發生變化。

有大量的類似的例子,DocumentBuilderFactoryTransformerFactory都是抽象但其newInstance()方法將返回一個亞類中,通常分開包裝(例如Saxon)。

但同樣的問題也有不同的解決方案:JDBC定義了Driver接口(而不是抽象類)和一個帶靜態方法的工具類來加載不同的驅動程序實現。數據庫驅動程序供應商不需要擴展抽象類,而是需要實現Driver接口。

順便說一句,要找到對象的實際運行時類,只需調用getClass()就可以了。

+0

[This answer](http://stackoverflow.com/a/1834836/1858327)另一個問題進一步解釋了爲什麼這些類不在文檔中。 –