我们能否创建一个接口的对象?

33
interface TestA {
    String toString();
}

public class Test {
    public static void main(String[] args) {
        System.out.println(new TestA() {
            public String toString() {
                return "test";
            }
        });
    }
}

以下是问题的答案:

A. test
B. null
C. 运行时会抛出异常。
D. 编译失败,因为第1行有一个错误。
E. 编译失败,因为第4行有一个错误。
F. 编译失败,因为第5行有一个错误。

这个问题的答案是C。调用a.test()会在运行时抛出NullPointerException。由于A没有实现任何方法,所以不能直接创建A的实例。但是,可以创建一个实现了A接口的类的实例,并将其赋值给A类型的变量。在这种情况下,变量包含对该类实例的引用,但只能访问A中定义的方法。

至于第二个问题,不能直接创建一个接口的实例。但是,可以通过创建一个实现该接口的类的实例来间接地创建接口的实例。

6个回答

92

你看到的是一个匿名内部类

给定以下接口:

interface Inter {
    public String getString();
}
您可以这样创建类的实例:
Inter instance = new Inter() {
    @Override
    public String getString() {
        return "HI";
    }
};

现在,您拥有了您所定义的接口的一个实例。但是,请注意,您实际上所做的是定义了一个实现该接口的类,并同时实例化了该类。


2
我正在寻找它。这是一个非常简短和简单的答案。对它的简洁性加一。 - amod
@SheikhAman 哈哈,我怀疑这个 OP 永远都不会选择一个正确的答案。 - Ungeheuer
1
所以,实际上是否调用了 System.out.println(innerObject.getString());,这就是为什么没有任何错误? - Koushik Shom Choudhury

5

test应该是输出结果。这是一个匿名内部类的示例。

这是一种非常常见的模式,使用Comparator接口作为闭包的仿真。


2
这个技巧不仅仅涉及到匿名内部类,它会打印出 test 是因为它重写了 toString 方法,当使用 System.out.println 打印一个对象时,它会隐式地调用它的 toString 方法。

1

也试试这个... 匿名类的名称是自动生成的!

Inter instance = new Inter() {
    public String getString() {
        return "HI" + this.getClass();
    }
};

0

我们可以创建一个实现接口的匿名类对象:

匿名类使您的代码更加简洁。它们使您能够同时声明和实例化一个类。它们类似于本地类,但它们没有名称。如果您只需要使用本地类一次,请使用它们。

如果您有一个声明了一个方法toString的接口,您可以先创建一个实现该接口的类,然后创建该类的对象:

interface TestA {
    String toString();
}

class TestB implements TestA {
    @Override
    public String toString() {
        return "test";
    }
}

public class Test {
    public static void main(String[] args) {
        System.out.println(new TestB());
    }
}

或者,您可以创建一个匿名类的对象来简化此代码:

interface TestA {
    String toString();
}

public class Test {
    public static void main(String[] args) {
        System.out.println(new TestA() {
            @Override
            public String toString() {
                return "test";
            }
        });
    }
}

在这两种情况下,它都会打印"test"


-2

我不知道这个问题的意义。如果这是一个面试问题,那么我可以说这还可以。但在实际情况下,这不是实现继承的正确方法。所以回答这个问题,你正在做的是匿名内部类

在这里,你正在实例化一个并通过编写继承来实现。

System.out.println(new TestA() {
    public String toString() {
        return “test”;
    }
}); 

当然,结果将会是test


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接