2015-05-01 80 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)另一个问题进一步解释了为什么这些类不在文档中。 –