6

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

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 是匿名类。但是由于我已经将它声明为接口,为什么它允许我创建同名的匿名类......?

再次...如果这些是匿名类,那么主类应该允许我给这些匿名类起任何名字..但是如果尝试这样做..我得到编译错误

4

4 回答 4

14

当你打印出一个对象时,它会调用 toString() 方法。在第一条语句中,您创建新对象并覆盖名为 toString 的方法。因此,在打印对象时会调用此 toString() 方法。

在第二个语句中,您还创建了一个对象,但您没有覆盖 toString() 方法,因此它将使用 Object 类的 toString() 方法。

对于新问题,此链接对您的理解有很好的解释: Anonymous Classes

这是解释的副本:

new className(optional argument list){classBody}

此表达式从一个未命名且先前未定义的类实例化一个新对象,该类自动扩展名为 className 的类,并且不能显式实现任何接口。新类的主体由 classBody 给出。

执行此表达式的结果是定义了一个扩展了 className的新类,实例化了新类的新对象,并将表达式替换为对新对象的引用

new interfaceName(){classBody}

此表达式从一个未命名且先前未定义的类实例化一个新对象,该类自动实现名为 interfaceName 的接口,并自动扩展名为 Object 的类。该类可以显式实现一个,并且只能实现一个 interface,并且不能扩展 Object 以外的任何类。再一次,新类的主体由 classBody 给出。

你现在清楚了吗?

于 2010-06-05T02:15:37.733 回答
3

首先,您从匿名实例println()中覆盖该方法,因此您会得到覆盖方法返回的字符串,这是该函数的默认行为。toString()myAbstractClasstoString()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";
            }
        }); 
    } 
}
于 2010-06-05T02:19:29.940 回答
3

myAbstractClass 是一个最小的类。它继承自对象。

类 main 从 myAbstractClass 构造两个匿名内部类,并打印它们的 toString 输出。

  1. 内部类覆盖了 toString 方法,您可以看到它的输出。
  2. 内部类添加了一个方法,并且您使用了默认的 toString 定义。
于 2010-06-05T02:23:37.480 回答
1

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

我认为您在第二种情况下期望函数调用是错误的。您刚刚覆盖了它,但从未调用过。

于 2010-06-05T02:26:49.437 回答