oops规则是“没有构造函数就没有类可以存在”。就ok.But中的java匿名类不能有任何构造函数。因为它没有任何名称。所以它与OOPS规则相矛盾。我真的很困惑。它是否打破了OOPS规则?请帮忙
答案 0 :(得分:3)
实际上,他们有一个隐式构造函数。假设你有:
class A {
A (B b, C b) {
//constructor code
}
}
因此,当您通过new A(b,c) {...}
创建A的匿名子类时,它有一个隐式构造函数,其主体为super(b,c)
。我想,匿名类不能拥有自己的显式coustructors的原因是java命名约定,构造函数名称必须与类名匹配。如果匿名类没有名称,那么就不能为它指定构造函数。
答案 1 :(得分:2)
每个Java类都有一个构造函数。您无法指定它,但您的Anonymous类获取默认构造函数。没有什么可以强迫你使用Anonymous类,你可以使用内部类。
答案 2 :(得分:2)
在匿名课程中
Foo foo = new Foo(x) {};
(x)
指定传递给超类构造函数的实际参数。
整个匿名类语法是 syntactic-sugar ,这是编译器转换为更基本的句法结构的缩写语法。
所以匿名类并不是真正的匿名。上面的示例类被分配了一个自动生成的名称,如Foo$1
,它有一个隐含的构造函数
Foo$1(T x) { super(x); }
其中T取自最具体的超类构造函数,其签名可以接受参数(x)
基于Java的基于静态类型的重写签名选择的常规规则。
答案 3 :(得分:2)
来自Java Doc:
匿名类是一个表达式。匿名类的语法 表达式就像构造函数的调用一样,除了那里 是一个包含在代码块中的类定义。
和
包含构造函数参数的括号,就像一个 普通类实例创建表达式。注意:实施时 接口,没有构造函数,所以你使用一对空 括号
示例强>
class Emp{
public static void main(String args[]){
Person p=new Person(){
void eat(){System.out.println("nice fruits");}
};
p.eat();
}
}
内部实施:
static class Emp$1 extends Person
{
Emp$1(){}
void eat()
{
System.out.println("nice fruits");
}
}
答案 4 :(得分:1)
<强> 15.9.5。匿名类声明
匿名类声明自动从类派生 Java编译器创建实例表达式。
匿名类永远不是抽象的(§8.1.1.1)。
匿名类总是隐含最终的(§8.1.1.2)。
匿名类始终是内部类(第8.1.3节);它永远不会 static(§8.1.1,§8.5.1)。
<强> 15.9.5.1。匿名构造函数
匿名类不能具有显式声明的构造函数。 相反,Java编译器必须自动提供匿名 匿名类的构造函数。匿名的形式 具有直接超类S的匿名类C的构造函数为 如下:
A. 如果S不是内部类,或者S是静态上下文中出现的本地类,那么匿名构造函数有一个正式的 类实例创建的每个实际参数的参数 声明C的表达式。
类实例创建表达式的实际参数用于确定S的构造函数cs,使用与 方法调用(§15.12)。
匿名构造函数的每个形式参数的类型必须与cs的相应形式参数相同。
构造函数的主体包含一个超级(...)形式的显式构造函数调用(第8.8.7.1节),其中实际的 arguments是顺序中构造函数的形式参数 他们被宣布了。
B。否则,C的构造函数的第一个形式参数表示i的直接封闭实例的值 尊重S.此参数的类型是类类型 立即附上S的声明。
构造函数为声明的类实例创建表达式的每个实际参数都有一个额外的形式参数 匿名课。第n个形式参数e对应于第n-1个 实际的论点。
类实例创建表达式的实际参数用于确定S的构造函数cs,使用与 方法调用(§15.12)。
匿名构造函数的每个形式参数的类型必须与cs的相应形式参数相同。
构造函数的主体由o.super(...)形式的显式构造函数调用(第8.8.7.1节)组成,其中o是第一个 构造函数的形式参数,实际参数是 构造函数的后续形式参数,按顺序排列 宣布了。
在所有情况下,匿名构造函数的throws子句必须列出 显式超类抛出的所有已检查异常 匿名中包含的构造函数调用语句 构造函数,以及任何实例抛出的所有已检查异常 初始化程序或匿名类的实例变量初始值设定项。
请注意,匿名签名是可能的 构造函数引用不可访问的类型(例如,如果这样的话 类型出现在超类构造函数cs的签名中。这个 本身不会在编译时或编译时导致任何错误 运行时间。
答案 5 :(得分:0)
即使是匿名类也有构造函数,只是你不能给它,而是编译器会自动为你提供它。