没有任何方法可以使用抽象类创建对象。但是当使用匿名内部类时,可以运行以下代码。不仅 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();
}
}
考虑以下代码(代码 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$1.class Demo.class Vehicle.class
除了我们在代码 1 中得到 Demo$1.class 和在代码 2 中得到 Demo$Car.class 之外,我们得到了相同的结果。
发生这种情况是因为代码 1 实际上是在创建一个继承自 Vehicle 的类。一个所谓的匿名类。该类没有名称 (*),但它仍然是一个完整的类,它继承自 Vehicle 并且可以像 Car 可以被实例化一样被实例化。
这段代码:
Vehicle v1=new Vehicle(){
不是实例化类 Vehicle 的对象。它正在实例化一个类的对象,该类继承自没有名称的 Vehicle。
(*) 其实它是有名字的。它的名字是“1 in Demo”又名 Demo$1。 JVM 需要一个名称才能运行它,您不能只告诉 JVM 运行某些东西而不告诉它运行什么。该名称不是类的语法上有效的名称;不能将类命名为 1。这是设计使然,因为它确保匿名类名不会与普通类名冲突。