Sav*_*ake 5 java anonymous inner-classes
没有任何方法可以使用抽象类创建对象.但是当使用匿名内部类时,可以运行以下代码.并且不仅该start()方法不可访问,因此在不给出任何编译错误的情况下运行以下程序的原因是什么以及访问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();
}
}
Run Code Online (Sandbox Code Playgroud)
考虑以下代码(代码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();
}
}
Run Code Online (Sandbox Code Playgroud)
毫不奇怪,前一段代码没有给出编译器错误.
汽车延伸车辆和汽车不是抽象的.因此,您可以实例化它.
让我们看看编译代码2时会发生什么:
javac *.java
list .class files
Demo$Car.class Demo.class Vehicle.class
Run Code Online (Sandbox Code Playgroud)
当编译问题(代码1)中的代码时会发生这种情况:
javac *.java
list .class files
Demo$1.class Demo.class Vehicle.class
Run Code Online (Sandbox Code Playgroud)
我们得到相同的,除了我们在代码1中获得Demo $ 1.class并在代码2中获得Demo $ Car.class.
这是因为代码1实际上创建了一个继承自Vehicle的类.一个所谓的匿名类.该类没有名称(*),但它仍然是一个完整的类,它继承自Vehicle并且可以实例化,就像Car可以实例化一样.
这段代码:
Vehicle v1=new Vehicle(){
Run Code Online (Sandbox Code Playgroud)
是不是实例化类的车辆的一个目的.它实例化一个继承自Vehicle的类的对象,该类没有名称.
(*)实际上它确实有一个名字.它的名字是"1 in Demo"又名Demo $ 1.JVM需要一个名称才能运行它,你不能只告诉JVM运行某些东西而不告诉它要运行什么.这个名称不是一个类的有效名称; 不能将类命名为1.这是通过dessign,因为它确保匿名类名不会与普通类名冲突.