关于实例化:实例化Java抽象类?

Instantiate Java Abstract class?

本问题已经有最佳答案,请猛点这里访问。

比较新的Java程序员和我已经被教导过,你不能创建一个抽象类的实例。我还做了一些研究,我了解到在大多数情况下,当一个抽象类被创建时,它实际上是一个匿名的子类。但我遇到的问题是:

Java的EDCOX1×0类有一个方法EDCOX1,1,它返回一个EDCOX1,2,}。EDCOX1 2是一个抽象类,Java文档还列出了它的所有子类抽象。所以我真的迷路了。退回什么?


返回的是API文档中找不到的非抽象子类,例如sun.net.www.protocol.http.HttpUrlConnection。如果在浏览器中的小程序中运行相同的代码,可能会得到不同的代码,通常是包装浏览器的本机连接的代码。

所以这里没有技巧也没有魔力,只是一些类不会出现在API文档中,因为它们被认为是实现内部的,并且会发生变化。

有许多类似的例子,DocumentBuilderFactoryTransformerFactory都是抽象的,但它们的newInstance()方法将返回一个子类,通常是单独包装的(例如saxon)。

但对于同一个问题也有不同的解决方案:JDBC用静态方法定义了Driver接口(而不是抽象类)和DriverManager实用程序类来加载不同的驱动程序实现。数据库驱动程序供应商不需要扩展抽象类,而是需要实现Driver接口。

顺便说一下,要找到对象的实际运行时类,只需调用它们的getClass()


openConnection返回一些具体类,扩展URLConnection。方法的签名被定义为返回URLConnection,因为使用它的代码不应该依赖于任何特定的实现。


这里将应用多态性概念。

对象的类型将是URLConnection(父类接口),对象将是其子类(扩展或实现(如果是接口))。

下面的例子可能会让您明白这一点。

1
2
3
abstract class URLConnection {
  // some methods.
}

假设你有自己的班级。

1
2
3
4
5
6
7
8
9
10
11
class ConnectionClass extends URLConnection {
  // some methods
}

class Main {
  URLConnection connect = null

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

您将返回类的对象,该对象提供了URLConnection类的openConnection()的实现。同样的概念也适用于接口案例。


可能是匿名类

比如说你有一个abstract class

1
2
3
abstract class Vehicle {
    abstract public void move();
}

不用制作一个class Car extends Vehicleclass Boat extends Vehicle,你可以用匿名类的魔力做到这一点。(这可能就是为什么JavaDoc没有说存在子类的原因,因为它是匿名的,因此不能被JavaDoc表示的公共API引用。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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

1
2
3
abstract class Vehicle {
    abstract public void move();
}

如果内部classprivate,那么只有封装它的类才能实例化它。(这可能就是为什么JavaDoc没有说存在子类的原因,因为它是私有的,因此对JavaDoc表示的公共API是隐藏的。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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 classes的问题,但它可能有助于回答URLopenConnectionURLConnection


它是一个扩展URLConnection的类,正在返回。这是一种隐藏实现细节的方法,因为可以根据输入参数返回URLConnection的不同实现。


当所有子类都是抽象的,那么这是因为只能通过在工厂中创建类来使用类。如果您仔细检查使用java.net.urlconnection来触发和处理HTTP请求中的代码,您将看到URLConnection对象从未被实例化。相反,我们是这样称呼openConnection的:

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