相对较新的Java程序员和我已经被教导过你不能创建一个抽象类的实例。我也做了一些研究,我了解到在大多数情况下,当它出现一个抽象类时,它实际上是一个匿名的子类。但这是我遇到的问题:
Java的openConnection
类有一个返回URLConnection
的方法URLConnection
。 WHERE field_name IS NULL
是一个抽象类,Java文档也将其所有子类列为抽象类......所以我真的迷失了。什么回来了?
答案 0 :(得分:16)
返回的内容是您在API文档中找不到的非抽象子类,例如sun.net.www.protocol.http.HttpUrlConnection
。如果您在浏览器中从applet运行相同的代码,您可能会得到一个不同的代码,通常包含浏览器的本机连接。
因此,没有任何技巧也没有魔力,只是有些课程没有出现在API文档中,因为它们被认为是实施的内部因素并且可能会发生变化。
有很多类似的例子,DocumentBuilderFactory
或TransformerFactory
都是抽象的,但它们的newInstance()
方法将返回一个子类,通常是单独打包的(例如Saxon)。< / p>
但同样问题也有不同的解决方案:JDBC定义Driver
接口(而不是抽象类),以及带有静态方法的DriverManager
实用程序类来加载不同的驱动程序实现。数据库驱动程序供应商不需要扩展抽象类,而是需要实现Driver
接口。
顺便说一下,要找到对象的实际运行时类,只需在它们上面调用getClass()
。
答案 1 :(得分:14)
.releasegroupingcategory
返回一些扩展openConnection
的具体类。方法的签名被定义为返回URLConnection
,因为使用它的代码不应该依赖于任何特定的实现。
答案 2 :(得分:10)
多态性概念将适用于此处。
对象的类型将是URLConnection(父类\接口),而对象将是其子类(扩展或实现(在接口的情况下))。
以下示例可能会让您明白这一点。
abstract class URLConnection {
// some methods.
}
我们假设您有自己的课程。
class ConnectionClass extends URLConnection {
// some methods
}
class Main {
URLConnection connect = null
public URLConnection getUrl() {
return connect = new ConnectionClass();
}
}
您将返回类的对象,该类提供openConnection()
类URLConnection
的实现。相同的概念适用于接口案例。
答案 3 :(得分:7)
假设您有abstract class
...
abstract class Vehicle {
abstract public void move();
}
如果没有制作class Car extends Vehicle
或class Boat extends Vehicle
,您可以使用匿名类的魔力来完成此操作。 (这可能就是为什么javadoc没有说子类是因为它是匿名的,因此不能被javadoc所代表的公共api引用。)
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;
}
}
所以没有你无法实例化abstract class
......但这并不是真的,你可以把它作为一个匿名类来实现并在现场实现这些方法。从技术上讲,这并没有实例化abstract class
,但是当你看到这种事情的时候,这就是很多事情。
再次说,你有abstract class
...
abstract class Vehicle {
abstract public void move();
}
如果内部class
是private
,那么只有包含它的类才能实例化它。 (这可能就是javadoc没有说子类的原因,因为它是私有的,因此隐藏在javadoc代表的公共api中。)
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
es的任何内容,但它可能有助于回答URL
,openConnection
和URLConnection
。
答案 4 :(得分:2)
这是一个正在退回的URLConnection
扩展的类。这是一种隐藏实现细节的方法,因为可以根据输入参数返回URLConnection
的不同实现。
答案 5 :(得分:1)
当所有子类都是抽象的时,那是因为你只能通过在工厂中创建它来使用这些类。如果仔细检查Using java.net.URLConnection to fire and handle HTTP requests中的代码,您将看到URLConnection
对象永远不会被实例化。相反,我们通过这样调用openConnection
得到它:
URLConnection connection = new URL(url + "?" + query).openConnection();