在Java中,当传递一个接口时,您能否实例化该接口?

3

For example, if I have an interface:

interface Executable {
    void execute();
}

您无法显式实例化它。如果您尝试创建一个接口Executable的新实例,您将收到一个编译错误,提示“无法实例化类型Executable”。

然而,在尝试将接口传递给一个方法时,我意识到您可以这样做:

class Runner {
    public void run(Executable e) {
        System.out.println("Executing block of code...");
        e.execute();
    }
}

public class App {
    public static void main(String[] args) {
        Runner r = new Runner();

        // When passing the Executable type, am I instantiating it?
        r.run(new Executable() {
            public void execute() {
                System.out.println("Executed!");
            }
        });

    }
}

这怎么可能?因为有new关键字,难道不是在创建接口Executable的新实例吗?是我理解有问题吗?请简要解释并举例说明,谢谢!


4
它被称为匿名类。 - Heisenberg
这被称为匿名类声明,而不是实例化。 - мυѕτавєւмo
2个回答

3

一个接口是提供需要实现的方法模板的类。您无法直接实例化一个接口,因为没有方法实现它将没有任何作用。

如果您实例化实现了接口的对象,则方法的实现已经提供并且实际上与您实例化具有相同方法实现的接口一样。在您的情况下,这被称为匿名类,只需提供必要的方法实现即可使用。拥有一个接口:

interface Executable {
    void execute();
}

实例化是:

Executable executable = new Executable() {
    @Override
    public void execute() {
        System.out.println("Executed!");
    }
}

在这里,您提供execute()方法的实现。由于该接口只有一个方法并且作为函数式接口,因此您可以使用Java 8中的lambda表达式简化它:

Executable executable = () ->  System.out.println("Executed!");

这正是我所需要的!我现在要研究一下lambda表达式。 - MattGotJava
我个人喜欢lambda表达式。r.run(() -> System.out.println("Executed!")); 看起来更好,对吧?:) 你甚至可以将所有的 main 方法缩短为:new Runner().run(() -> System.out.println("Executed!")); - Nikolas Charalambidis

1

你并不是因为使用 new 关键字而创建了接口 Executable 的新实例。事实上,你正在实例化一个实现 Exceutable 接口的匿名内部类。

下面是如何在 Java 中创建线程的示例。

Thread t= new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("Hello World!");

            }
        });

在Thread构造函数中,我们传递了一个实现了接口Runnable的匿名内部类。

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