任何人都可以解释以下代码的工作吗?

时间:2010-06-05 02:10:54

标签: java interface abstract-class anonymous-class

有人可以解释以下代码的工作吗?

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应该允许我给这些匿名类赋予任何名称..但是如果尝试这样做......我得到编译错误

4 个答案:

答案 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输出。

  1. 内部类重写了toString方法,您可以看到它的输出。
  2. 内部类添加了一个方法,并且您使用默认的toString定义。

答案 3 :(得分:1)

在这两种情况下,您都打印了该对象。因此它会调用对象的toString()方法。在第一种情况下,由于您已覆盖toString()方法,因此它正在打印myAbstractClass toString。在第二种情况下,由于它未被覆盖,因此会调用toString()类中实现的默认Object

我认为你期望第二种情况下的函数调用是错误的。你刚刚覆盖它但从未打过电话。