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

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

没有任何方法可以使用抽象 class 创建对象。但是当使用匿名内部 class 时,可以 运行 以下代码。不仅 start() 方法不可访问,因此 运行ning 后面的程序没有给出任何编译错误的原因是什么,访问 start() 方法的机制是什么。

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();
        }
    }

这正是抽象的想法 classes。你不能实例化抽象class,但你可以实例化它的任何子class实现抽象方法。这样的子 classes 可以是具体的 classes,也可以是匿名的 classes,就像你在这里做的那样,所以这段代码没有理由不编译

Anonymous class 表示您在 Demo 中声明了本地 class。匿名class是一个表达式,可以实现抽象方法。主要是匿名 class 是 interfaceabstract class 的本地实现,它必须包含抽象方法的实现和抽象 class 的抽象方法的相同实现方式。因此,简而言之,您可以使用匿名 class 实例化 abstract class。

在这里,您实际上是在您的 Demo 中声明您的整个 class Vehicle 为匿名 class 并需要实施。请注意,在编译 Demo class 之后,您将拥有 Demo.class 文件,这是一个 anonymous class 并实现了 VehicleDemo.

虽然您正在编写 new Vehicle() 但它并未创建 Vehicle class 的实例。它创建了一个没有任何名称的 Vehicle 子类型的实例

考虑以下代码(代码 2)。

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();
   }
}

前面的代码没有出现编译错误也就不足为奇了。
Car extends Vehicle 并且 Car 不是抽象的。因此你可以实例化它。

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

javac *.java
list .class files
Demo$Car.class  Demo.class  Vehicle.class

这就是编译问题中的代码(代码 1)时发生的情况:

javac *.java
list .class files
Demo.class  Demo.class  Vehicle.class

除了我们在代码 1 中得到 Demo$1.class 和在代码 2 中得到 Demo$Car.class 之外,我们得到相同的结果。
发生这种情况是因为代码 1 实际上正在创建一个继承自 Vehicle 的 class。一个所谓的匿名class。 class 没有名称 (*),但它仍然是一个完整的 class,它继承自 Vehicle 并且可以像 Car 可以被实例化一样被实例化。

此代码:

Vehicle v1=new Vehicle(){

不是实例化class车辆的对象。它正在实例化一个 class 的对象,它继承自没有名称的 Vehicle。

(*) 其实它是有名字的。它的名字是“1 in Demo”又名 Demo$1。 JVM 需要一个名称才能 运行 它,你不能只告诉 JVM 运行 什么而不告诉它 运行 什么。该名称不是 class 语法上有效的名称;无法将 class 命名为 1。这是设计使然,因为它确保匿名 class 名称不会与正常 class 名称冲突。

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 创建一个 anonymous class 时,您实际上是在创建 一个新的 class extending/implementing 到 abstract classinterface.

是否使用内部 class 并不重要。


简而言之,当您创建匿名 class 时,它是扩展抽象 class 的新 "nameless" class 被实例化!