为什么不在java中的匿名类中使用构造函数?它与OOP的规则相矛盾
oops规则是“没有构造函数就没有类可以存在”。没关系。但是在java中,匿名类只能有它的构造函数。因为它没有任何名称。 所以它与OOPS规则相矛盾。我真的很困惑。它是否打破了OOPS规则?请帮忙
实际上,他们有一个隐式构造函数。 假设你有:
class A { A (B b, C b) { //constructor code } }
所以当你通过new A(b,c) {...}
创建A的匿名子类时,它有一个带有body super(b,c)
隐式构造函数。 我想,匿名类不能拥有自己的显式coustructors的原因是java命名约定,构造函数名称必须与类名匹配。 如果匿名类没有名称,则无法为其指定构造函数。
每个Java类都有一个构造函数。 您无法指定它,但您的Anonymous类获取默认构造函数。 没有什么可以强迫你使用Anonymous类,你可以使用内部类。
在匿名课堂上
Foo foo = new Foo(x) {};
(x)
指定传递给超类构造函数的实际参数。
整个匿名类语法是syntactic-sugar ,这是一种缩写语法,编译器将其转换为更基本的语法结构。
所以匿名类并不是真正的匿名。 上面的示例类被赋予一个自动生成的名称,如Foo$1
,它有一个隐含的表单构造函数
Foo$1(T x) { super(x); }
其中T取自最具体的超类构造函数,其签名可以接受基于Java的常规规则的参数(x)
,用于在基于静态类型的重写签名中进行选择。
来自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"); } }
参考: 匿名类的示例
从Java语言规范
15.9.5。 匿名类声明
Java编译器自动从类实例创建表达式派生匿名类声明。
匿名类永远不是抽象的(第8.1.1.1节)。
匿名类总是隐式最终的(第8.1.1.2节)。
匿名类始终是内部类(第8.1.3节); 它永远不会是静态的(§8.1.1,§8.5.1)。
15.9.5.1。 匿名构造函数
匿名类不能具有显式声明的构造函数。 相反,Java编译器必须自动为匿名类提供匿名构造函数。 具有直接超类S的匿名类C的匿名构造函数的forms如下:
A.如果S不是内部类,或者S是静态上下文中出现的本地类,则匿名构造函数对于声明C的类实例创建表达式的每个实际参数都有一个forms参数。
类实例创建表达式的实际参数用于确定S的构造函数cs,使用与方法调用相同的规则(第15.12节)。
匿名构造函数的每个forms参数的类型必须与cs的相应forms参数相同。
构造函数的主体由super(…)forms的显式构造函数调用(第8.8.7.1节)组成,其中实际参数是构造函数的forms参数,按它们的声明顺序。
B.否则,C的构造函数的第一个forms参数表示相对于S的直接封闭的i实例的值。该参数的类型是立即包含S的声明的类类型。
构造函数为声明匿名类的类实例创建表达式的每个实际参数都有一个附加的forms参数。 第n个forms参数e对应于第n-1个实际参数。
类实例创建表达式的实际参数用于确定S的构造函数cs,使用与方法调用相同的规则(第15.12节)。
匿名构造函数的每个forms参数的类型必须与cs的相应forms参数相同。
构造函数的主体由o.super(…)forms的显式构造函数调用(第8.8.7.1节)组成,其中o是构造函数的第一个forms参数,实际参数是后续的forms参数。构造函数,按它们声明的顺序。
在所有情况下,匿名构造函数的throws子句必须列出匿名构造函数中包含的显式超类构造函数调用语句抛出的所有已检查exception,以及匿名类的任何实例初始值设定项或实例变量初始值设定项抛出的所有已检查exception。
请注意,匿名构造函数的签名可能引用不可访问的类型(例如,如果此类型出现在超类构造函数cs的签名中)。 这本身不会在编译时或运行时导致任何错误。
即使是匿名类也有构造函数,只是你不能给它,而是编译器会自动为你提供它。