[英]How does this Java code instantiate an abstract class?
我正在更改我们的Java类,我注意到以下代码行:
OurClass<OurInterface1> ourClass = new OurClass<OurInterface1>() {};
我OurClass
一行感到奇怪的是, OurClass
是一个抽象类 - 这里是OurClass
的定义:
public abstract class OurClass<T extends OurInterface1> implements OurInterface2<T>
当我删除行末尾的{}
时,Eclipse告诉我Cannot instantiate the type OurClass<OurInterface1>
,但当我把{}
放回去时,一切正常。
{}
如何允许您实例化一个抽象类?
添加{}
引入了匿名内部类的语法。
匿名类表达式包含以下内容:
新的运营商
要实现的接口的名称或要扩展的类。 在此示例中,匿名类正在实现接口HelloWorld。
括号,包含构造函数的参数,就像普通的类实例创建表达式一样。 注意:实现接口时,没有构造函数,因此您使用一对空括号,如本例所示。
身体,是一个类声明体。 更具体地说,在正文中,方法声明是允许的,但语句不是。
您正在声明一个匿名内部类,它是OurClass
子类。 这个类的主体是空的: {}
。 这个匿名内部类不是abstract
,因此您可以实例化它。
当你删除{}
,编译器认为你直接实例化了一个abstract
类OurClass
,所以它不允许它。
调用new
运算符后的块( new OurClass<OurInterface1>() {}
)实际上是创建一个扩展OutClass
的匿名类的实例。
由于这个类不再是abstract
,因此实例化它没有问题。
实际上,当您实例化接口或可扩展类时,您可以实时扩展和覆盖方法。 这称为匿名内部类。
你在你的例子中所做的是创建一个匿名的内部类,但它没有任何效果,因为你没有覆盖任何东西。 您可以将重写的方法放在那些大括号{}
。
OurClass<OurInterface1> ourClass = new OurClass<OurInterface1>() {};
匿名内部类的常用应用是在Runnable
接口上,该接口定义了一个void run()
方法。 您可以隐式实例化实现Runnable
的对象并动态覆盖run()
。
Runnable someTask = new Runnable() {
@Override
public void run() {
System.out.println("Running a task!");
}
};
许多开发人员都不喜欢匿名内部类,因为它们非常冗长。 幸运的是,在Java 8中,您可以使用lambda表达式来替换实现单个方法的大多数匿名内部类。 编译器基本上为您推断了匿名内部类,允许您更简洁地编写代码。
Runnable someTask = () -> System.out.println("Running a task!");
如果不在类中实现抽象函数,则无法实例化抽象类。 这通常通过使用已实现的类实现抽象类来完成。 请参阅: https : //docs.oracle.com/javase/tutorial/java/IandI/abstract.html
在您的情况下,实例化后使用的{}允许您在抽象类中实现任何抽象函数。
例如,
考虑
public abstract class DummyClass {
abstract void test() ;
}
是具有抽象函数的抽象类。
该课程可以通过以下方式发起:
DummyClass d = new DummyClass(){
void test(){
//test() implementation here
}
} ;
希望这可以帮助! :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.