我了解到我们无法实例化一个抽象类。但今天我测试了一些代码,我对此感到困惑。
package MainPackage;
abstract class abstractClass {
abstract abstractClass a_function();
}
public class Src {
abstractClass m;
public abstractClass abstractClassTest() {
return m.a_function();
}
public static void main(String args[]) {
System.out.println("Hello world!");
}
}
这里我创建了一个抽象类 abstractClass ,并在abstractClassTest()函数中返回它。它编译成功没有错误! IMO在返回之前,计算机应该创建该类型的对象。在这里它应该在 返回m.function() 之前创建 abstractClass 的对象,这是我无法理解的。我认为 我们无法实例化抽象类 意味着我们 无法创建抽象类的对象 或者我们 无法修改新课程(例如abstractClass m = new abstractClass() is illegal
) 。但是从上面的代码中,我们似乎可以创建一个抽象类的对象。它怎么能实现?对于代码abstractClass m
,计算机在看到代码时会做什么?我们不能说java已经为代码m
实例化了抽象类abstractClass m
?如果java不实例化类abstractClass
,它如何在代码abstractClass
中返回abstract abstractClass a_function();
的对象?
答案 0 :(得分:5)
是的,应该编译而不会出错。如果您曾调用NullPointerException
,它会在执行时抛出abstractClassTest
,因为您从未初始化m
变量以引用实际实例。为了做到这一点,你必须创建一个具体的类,它将你的抽象类作为子类。
例如:
public class ConcreteClass extends AbstractClass {
@Override AbstractClass a_function() {
return this;
}
}
public class Src {
private AbstractClass m = new ConcreteClass();
public AbstractClass abstractClassTest() {
return m.a_function();
}
public static void main(String args[]) {
new Src().abstractClassTest();
}
}
请注意,代码中没有任何内容可以创建抽象类的实例。仅仅因为你有一个该类型的变量并不意味着已经创建了该类型的对象。
答案 1 :(得分:1)
m永远不会被分配,你永远不会尝试使用new关键字实例化一个新的abstractClass。如果您的代码实际上已经到了abstractClassTest,那么您将获得一个空指针异常。我想你可能会混淆声明一个变量并实际给它一个值。
答案 2 :(得分:0)
您不能直接实例化抽象类,而您的代码实际上并不这样做。你所拥有的仅仅是对某个子类或其他抽象类的引用,当你来实例化'm'时,你必须提供一个实际的具体子类。
您获得了与接口类似的模式。写作是非常合法的,例如:
List m;
...
m.size();
但是当你实例化时,你会使用一个实现子类,例如:
List m;
...
m = new ArrayList();
...
m.size();
注意在实例化时,我们使用的是ArrayList,而不是List(只是接口)。