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

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

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

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抽象类的子类。严格来说,它并不等同于实例化抽象类本身。OTOH,每个子类实例都是其所有超类和接口的实例,因此大多数抽象类确实是通过实例化它们的一个具体子类来实例化的。

如果面试官只是说“错了!”而没有解释,并给出了这个例子作为一个独特的反例,我认为他不知道自己在说什么。

其他回答

你可以观察到:

为什么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

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

技术部分在其他答案中已经很好地涵盖了,它主要以: “他错了,他什么都不懂,让他加入SO,把一切都弄清楚:)”

我想说明一个事实(在其他回答中已经提到过),这可能是一个压力问题,也是许多面试官更多了解你以及你如何应对困难和不寻常情况的重要工具。通过给你错误的密码,他可能想看看你是否会反驳。要知道在类似的情况下,你是否有信心站起来对抗你的前辈。

附注:我不知道为什么,但我有一种感觉,面试官已经读了这篇文章。

上面实例化了一个匿名的内部类,它是my抽象类的子类。严格来说,它并不等同于实例化抽象类本身。OTOH,每个子类实例都是其所有超类和接口的实例,因此大多数抽象类确实是通过实例化它们的一个具体子类来实例化的。

如果面试官只是说“错了!”而没有解释,并给出了这个例子作为一个独特的反例,我认为他不知道自己在说什么。

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

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

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

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

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

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