我们可以实例化一个抽象类吗? [英] Can we instantiate an abstract class?

查看:30
本文介绍了我们可以实例化一个抽象类吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的一次采访中,有人问我我们是否可以实例化一个抽象类?"

During one of my interview, I was asked "If we can instantiate an abstract class?"

我的回答是不,我们不能".但是,面试官告诉我错了,我们可以."

My reply was "No. we can't". But, interviewer told me "Wrong, we can."

我对此有点争论.然后他告诉我自己在家里试试这个.

I argued a bit on this. Then he told me to try this myself at home.

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

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

在这里,我正在创建我的类的实例并调用抽象类的方法.任何人都可以向我解释一下吗?面试时我真的错了吗?

Here, I'm creating instance of my class and calling method of abstract class. Can anyone please explain this to me? Was I really wrong during my interview?

推荐答案

在这里,我正在创建我的类的实例

Here, i'm creating instance of my class

不,您不是在此处创建抽象类的实例.相反,您正在创建抽象类的匿名子类 的实例.然后你在你的抽象类引用上调用该方法指向子类对象.

No, you are not creating the instance of your abstract class here. Rather you are creating an instance of an anonymous subclass of your abstract class. And then you are invoking the method on your abstract class reference pointing to subclass object.

此行为在 中明确列出JLS - 第 15.9.1 节:-

如果类实例创建表达式以类体结尾,则被实例化的类是一个匿名类.然后:

If the class instance creation expression ends in a class body, then the class being instantiated is an anonymous class. Then:

  • 如果 T 表示一个类,则声明由 T 命名的类的匿名直接子类.这是一个编译时错误,如果T 表示的类是最终类.
  • 如果 T 表示一个接口,则声明一个实现由 T 命名的接口的 Object 的匿名直接子类.
  • 在任何一种情况下,子类的主体都是类实例创建表达式中给出的 ClassBody.
  • 被实例化的类是匿名子类.

强调我的.

此外,在 JLS - 部分# 12.5,您可以阅读对象创建过程.我将在此处引用其中的一项声明:-

Also, in JLS - Section # 12.5, you can read about the Object Creation Process. I'll quote one statement from that here: -

每当创建新的类实例时,都会分配内存空间为它为类中声明的所有实例变量留出空间类型和在每个超类中声明的所有实例变量类类型,包括所有可能隐藏的实例变量.

Whenever a new class instance is created, memory space is allocated for it with room for all the instance variables declared in the class type and all the instance variables declared in each superclass of the class type, including all the instance variables that may be hidden.

就在对新创建的对象的引用作为结果,指示的构造函数被处理以初始化新的对象使用以下过程:

Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:

您可以在我提供的链接上阅读完整的程序.

You can read about the complete procedure on the link I provided.

要实际看到被实例化的类是一个匿名子类,您只需要编译这两个类.假设您将这些类放在两个不同的文件中:

To practically see that the class being instantiated is an Anonymous SubClass, you just need to compile both your classes. Suppose you put those classes in two different files:

My.java:

abstract class My {
    public void myMethod() {
        System.out.print("Abstract");
    }
}

Poly.java:

class Poly extends My {
    public static void main(String a[]) {
        My m = new My() {};
        m.myMethod();
    }
}

现在,编译两个源文件:

Now, compile both your source files:

javac My.java Poly.java

现在在编译源代码的目录中,您将看到以下类文件:

Now in the directory where you compiled the source code, you will see the following class files:

My.class
Poly$1.class  // Class file corresponding to anonymous subclass
Poly.class

看到那个类 - Poly$1.class.它是由编译器创建的类文件,对应于您使用以下代码实例化的匿名子类:

See that class - Poly$1.class. It's the class file created by the compiler corresponding to the anonymous subclass you instantiated using the below code:

new My() {};

所以,很明显有一个不同的类正在被实例化.只是,那个类只有在编译器编译后才会给它一个名字.

So, it's clear that there is a different class being instantiated. It's just that, that class is given a name only after compilation by the compiler.

通常,类中的所有匿名子类都将以这种方式命名:

In general, all the anonymous subclasses in your class will be named in this fashion:

Poly$1.class, Poly$2.class, Poly$3.class, ... so on

这些数字表示那些匿名类在封闭类中出现的顺序.

Those numbers denote the order in which those anonymous classes appear in the enclosing class.

这篇关于我们可以实例化一个抽象类吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆