有人可以解释以下代码的工作吗?
interface myInterface{}
public class Main {
public static void main(String[] args) {
System.out.println(new myInterface(){public String toString(){return "myInterfacetoString";}});
System.out.println(new myInterface(){public String myFunction(){return "myInterfacemyFunction";}});
}
}
输出是......
myInterfacetoString
primitivedemo.Main$2@9304b1
所有答案都说println()语句中的myInterface是匿名类。但是因为我已经将它声明为接口,为什么它允许我创建同名的匿名类....?
再次......如果这些是匿名类,那么class main应该允许我给这些匿名类赋予任何名称..但是如果尝试这样做......我得到编译错误
答案 0 :(得分:14)
当您打印出一个对象时,它将调用toString()方法。在第一个语句中,您创建了新对象,并且还覆盖了名为toString的方法。因此,在打印对象时会调用此toString()方法。
在第二个语句中,您还创建了一个对象,但是您没有覆盖toString()方法,因此它将使用Object类的toString()方法。
对于新问题,此链接对您的理解有很好的解释: Anonymous Classes
以下是解释的副本:
new className(optional argument list){classBody}
此表达式从未命名且以前未定义的类中实例化一个新对象,自动扩展名为className的类,无法显式实现任何接口。新类的主体由classBody给出。
执行此表达式的结果是定义了一个扩展className的新类,实例化了新类的新对象,并且表达式被新对象的引用替换。
new interfaceName(){classBody}
此表达式从未命名且以前未定义的类实例化新对象,它自动实现名为interfaceName的接口,并自动扩展名为Object 的类。该类可以显式实现一个,只有一个接口,而不能扩展除Object 以外的任何类。同样,新类的主体由classBody给出。
现在对你说清楚了吗?
答案 1 :(得分:3)
在第一个println()
上,您将覆盖匿名toString()
实例中的myAbstractClass
方法,因此您获得了覆盖toString()
方法返回的字符串,这是默认值println()
函数的行为。
在第二个println()
上,您没有覆盖toString()
方法,因此println()
使用默认方法(继承自Object
)。
在旁注中,尝试正确格式化代码,更容易阅读和理解。
abstract class myAbstractClass{}
public class Main {
public static void main(String[] args) {
System.out.println(new myAbstractClass(){
public String toString(){
return "myAbstractClass toString";
}
});
System.out.println(new myAbstractClass(){
public String myFunction(){
return "myAbstractClass myFunction";
}
});
}
}
答案 2 :(得分:3)
myAbstractClass是一个最小的类。它继承自object。
Class main从myAbstractClass构造两个匿名内部类,并打印它们的toString输出。
答案 3 :(得分:1)
在这两种情况下,您都打印了该对象。因此它会调用对象的toString()
方法。在第一种情况下,由于您已覆盖toString()
方法,因此它正在打印myAbstractClass toString
。在第二种情况下,由于它未被覆盖,因此会调用toString()
类中实现的默认Object
。
我认为你期望第二种情况下的函数调用是错误的。你刚刚覆盖它但从未打过电话。