在我的一次面试中,有人问我:“我们是否可以实例化一个抽象类?”

我的回答是:“没有。我们不能”。但是,面试官告诉我:“错了,我们可以。”

我对此进行了一些争论。然后他让我自己在家试试。

abstract class my {
    public void mymethod() {
        System.out.print("Abstract");
    }
}

class poly {
    public static void main(String a[]) {
        my m = new my() {};
        m.mymethod();
    }
}

在这里,我正在创建我的类的实例和调用抽象类的方法。有人能给我解释一下吗?我的面试真的错了吗?


当前回答

= my() {};意味着有一个匿名的实现,而不是简单的对象实例化,它应该是:= my()。你永远不能实例化一个抽象类。

其他回答

扩展类并不意味着实例化类。实际上,在您的示例中,您正在创建子类的一个实例。

我非常确定抽象类不允许初始化。所以,我会说不:你不能实例化一个抽象类。但是,您可以扩展/继承它。

你不能直接实例化一个抽象类。但这并不意味着您不能间接获得类的实例(实际上不是原始抽象类的实例)。我的意思是你不能实例化原始的抽象类,但是你可以:

创建一个空类 从抽象类继承 实例化派生类

因此,您可以通过派生类实例访问抽象类中的所有方法和属性。

不,你不能实例化一个抽象类。我们只实例化匿名类。在抽象类中,我们只声明抽象方法和定义具体方法。

实际上,我们不能直接创建抽象类的对象。我们创建的是一个抽象调用的引用变量。引用变量用于引用继承抽象类的类的对象,即抽象类的子类。

你可以简单地回答,只用一行

不,你永远不能实例化抽象类

但是,面试官仍然不同意,那么你可以告诉他/她

你所能做的就是创建一个匿名类。

并且,根据匿名类,类声明和实例化在同一位置/行

所以,面试官可能会对你的自信程度和你对OOPs的了解程度感兴趣。

你可以观察到:

为什么poly扩展my?这没用…… 编译的结果是什么?三个文件:my.class, poly.class和poly$1.class 如果我们可以这样实例化一个抽象类,我们也可以实例化一个接口……奇怪的……

我们可以实例化一个抽象类吗?

不,我们不能。我们可以做的是,创建一个匿名类(这是第三个文件)并实例化它。

那么超类实例化呢?

抽象超类不是由我们实例化的,而是由java实例化的。

编辑:请他测试一下

public static final void main(final String[] args) {
    final my m1 = new my() {
    };
    final my m2 = new my() {
    };
    System.out.println(m1 == m2);

    System.out.println(m1.getClass().toString());
    System.out.println(m2.getClass().toString());

}

输出是:

false
class my$1
class my$2