关于java:是否可以使用匿名内部类和机制来实例化抽象类来访问其中的方法

Is it possible to instantiate abstract class using anonymous inner class and mechanism to access method within it

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

无法使用抽象类创建对象。但当使用匿名内部类时,可以运行以下代码。不仅start()方法不可访问,那么在不给出编译错误的情况下运行后续程序的原因是什么?访问start()方法的机制是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
abstract class Vehicle{
        abstract void park();
    }  

    class Demo{
        public static void main(String args[]){
            Vehicle v1=new Vehicle(){
                int speed;
                void park(){
                    System.out.println("Parking for cars...");
                }
                void start(){
                    System.out.println("Start...");
                }
            };
            v1.park();
        }
    }

考虑下面的代码(代码2)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
abstract class Vehicle{
    abstract void park();
}  

class Demo{
  static class Car extends Vehicle {
       int speed;
       void park(){
                System.out.println("Parking for cars...");
       }
   }

   public static void main(String args[]){
        Vehicle v1=new Car();
        v1.park();
   }
}

毫不奇怪,前一段代码没有出现编译器错误。汽车延伸了汽车,汽车不是抽象的。因此,您可以实例化它。

让我们看看编译代码2时会发生什么:

1
2
3
javac *.java
list .class files
Demo$Car.class  Demo.class  Vehicle.class

当问题中的代码(代码1)被编译时会发生这种情况:

1
2
3
javac *.java
list .class files
Demo$1.class  Demo.class  Vehicle.class

除了代码1中的demo$1.class和代码2中的demo$car.class之外,我们得到了相同的结果。这是因为代码1实际上创建了一个继承自车辆的类。所谓的匿名类。该类没有名称(*),但它仍然是一个完整的类,继承自车辆,可以像实例化汽车一样进行实例化。

此代码:

1
Vehicle v1=new Vehicle(){

不是实例化类车辆的对象。它正在实例化从没有名称的车辆继承的类的对象。

(*)实际上它确实有一个名称。它的名字是"演示中的1",也就是演示$1。JVM需要一个名称来运行它,你不能不告诉它运行什么就告诉它运行什么。名称不是类的初始有效名称;不能将类命名为1。这是通过dessign实现的,因为它可以确保注释性类名不会与普通类名冲突。


这正是抽象类中的思想。不能声明抽象类,但可以声明实现抽象方法的抽象类的任何子类。这些子类可以是具体的类,也可以是匿名的类,就像您在这里所做的那样,因此没有理由不编译此代码。


There is no any way to create object using abstract class. But when using anonymous inner class it is possible to run the following code. What is the reason for runinng following program without giving any compile error.

代码运行是因为您没有直接从abstract class实例化对象。从abstract classinterface创建匿名类时,实际上是在创建一个扩展/实现到abstract classinterface的新类。

不管你是否在使用一个内部类,这都无关紧要。

简而言之,当您创建一个匿名类时,它是一个新的"无名称"类,它扩展了抽象类并被实例化!


虽然您正在编写new vehicle(),但它没有创建vehicle类的实例。它创建了一个没有任何名称的车辆子类型的实例


匿名类意味着您已经在自己的Demo中声明了本地class。匿名类是可以实现抽象方法的表达式。匿名类主要是interfaceabstractclass的本地实现,它必须包含抽象方法的实现和抽象类抽象方法的相同实现。因此,简而言之,您可以用匿名类实例化abstract类。

在这里,您实际上声明您的整个类Vehicle为您的Demo中的匿名类,并具有所需的实现。注意,在编译Demo类(匿名类)并在Demo中实现Vehicle之后,您将得到Demo$1.class文件。