相對較新的Java程序員,我被教導你不能創建一個抽象類的實例。我也做了一些小小的研究,我發現在大多數情況下,當它出現一個抽象類時,它實際上是一個匿名的子類。但這是我碰到的問題:實例化Java抽象類?
Java的URL
類有一個方法openConnection
返回URLConnection
。 URLConnection
是一個抽象類,Java文檔也列出了它的所有子類作爲抽象.....所以我真的迷失了。什麼是返回?
相對較新的Java程序員,我被教導你不能創建一個抽象類的實例。我也做了一些小小的研究,我發現在大多數情況下,當它出現一個抽象類時,它實際上是一個匿名的子類。但這是我碰到的問題:實例化Java抽象類?
Java的URL
類有一個方法openConnection
返回URLConnection
。 URLConnection
是一個抽象類,Java文檔也列出了它的所有子類作爲抽象.....所以我真的迷失了。什麼是返回?
這是繼續返回的類URLConnection
。這是一種隱藏實現細節的方法,因爲可以根據輸入參數返回URLConnection
的不同實現。
openConnection
返回一些延伸URLConnection
的具體類。該方法的簽名定義爲返回URLConnection
,因爲使用它的代碼不應該依賴任何特定的實現。
答案是正確的,但我不認爲它回答了什麼是實際返回的問題。 –
多態概念適用於此。
對象的類型將是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();
}
}
您將返回類,誰給的實施URLConnection
類openConnection()
的對象。相同的概念適用於界面的情況。
當所有的子類都是抽象的,那是因爲你只能通過在工廠中創建它來使用類。如果您仔細檢查Using java.net.URLConnection to fire and handle HTTP requests中的代碼,您將看到URLConnection
對象從未實例化過。取而代之的是,我們得到它通過調用openConnection
這樣的:
URLConnection connection = new URL(url + "?" + query).openConnection();
假設你有一個abstract class
...
abstract class Vehicle {
abstract public void move();
}
而沒有作出class Car extends Vehicle
或class 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
......但這並不是真正的全部事實,你可以將它作爲一個匿名類來實現,並且可以實現這些方法。儘管這在技術上並不是實例化的,但是當你看到這種事情時,它會得到很多。
再次,說你有一個abstract class
...
abstract class Vehicle {
abstract public void move();
}
如果內class
是private
那麼只有被包圍它可以初始化它的類。 (這或許就是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
,openConnection
和URLConnection
。
返回的內容是您在API文檔中找不到的非抽象子類,例如sun.net.www.protocol.http.HttpUrlConnection
。如果您在瀏覽器中從applet運行相同的代碼,您可能會得到不同的代碼,通常是包裝瀏覽器本地連接的東西。
因此,這裏沒有任何技巧也沒有什麼魔法,只是有些類不會顯示在API文檔中,因爲它們被認爲是實現的內部特徵,可能會發生變化。
有大量的類似的例子,DocumentBuilderFactory
或TransformerFactory
都是抽象但其newInstance()
方法將返回一個亞類中,通常分開包裝(例如Saxon)。
但同樣的問題也有不同的解決方案:JDBC定義了Driver
接口(而不是抽象類)和一個帶靜態方法的工具類來加載不同的驅動程序實現。數據庫驅動程序供應商不需要擴展抽象類,而是需要實現Driver
接口。
順便說一句,要找到對象的實際運行時類,只需調用getClass()
就可以了。
[This answer](http://stackoverflow.com/a/1834836/1858327)另一個問題進一步解釋了爲什麼這些類不在文檔中。 –
「URLConnection」的一個子類,就像你說的。 –
返回的'URLConnection'的具體類可能被標記爲'private'。 –
也看看http://stackoverflow.com/questions/2793150/using-java-net-urlconnection-to-fire-and-handle-http-requests。 – mattias