没有任何方法可以使用抽象类创建对象。但是当使用匿名内部类时,可以运行以下代码。并且不仅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();
}
}
答案 0 :(得分:6)
考虑以下代码(代码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();
}
}
前一段代码没有给出编译器错误也就不足为奇了 汽车延伸车辆和汽车不是抽象的。因此,您可以实例化它。
让我们看看编译代码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(){
NOT 实例化Vehicle类的对象。它实例化一个继承自Vehicle的类的对象,该类没有名称。
(*)实际上它确实有一个名字。它的名字是“1 in Demo”又名Demo $ 1。 JVM需要一个名称才能运行它,你不能只告诉JVM运行某些东西而不告诉它要运行什么。这个名称不是一个类的有效名称;不能将类命名为1.这是dessign,因为它确保匿名类名不会与普通类名冲突。
答案 1 :(得分:4)
这正是抽象类中的想法。您不能实例化抽象类,但您可以实现其实现抽象方法的任何子类。这样的子类可以是具体的类,也可以是像你这样的匿名类,所以没有理由不编译这段代码
答案 2 :(得分:1)
Anonymous class表示您已在class
中声明了本地Demo
。匿名类是一个表达式,它可以实现抽象方法。主要是匿名类是interface
或abstract
class
的本地实现,它必须包含抽象方法的实现和抽象类抽象方法的相同方式实现。因此,简而言之,您可以使用匿名类实例化abstract
类。
在这里,您实际上是在Vehicle
中将所有类Demo
声明为匿名类,并且需要实现。请注意,在编译Demo$1.class
类后,您将获得Demo
文件,该类是匿名类,并在Vehicle
中实现Demo
。< / p>
答案 3 :(得分:1)
虽然您正在编写新的Vehicle()但它没有创建Vehicle类的实例。它创建了一个没有任何名称
的Vehicle子类型的实例答案 4 :(得分:1)
没有任何方法可以使用抽象类创建对象。但是当使用匿名内部类时,可以运行以下代码。在没有给出任何编译错误的情况下运行程序的原因是什么。
代码运行是因为您不直接从abstract class
实例化对象。当您从abstract class
或interface
创建匿名类时,您实际上正在创建新类扩展/实施abstract class
或interface
。
无论您是否使用内部课程,这都无关紧要。
简而言之,当你创建一个匿名类时,它就是新的&#34;无名的&#34;扩展抽象类的类得到实例化!