【问题标题】:Why can variables be assigned to interface type?为什么可以将变量分配给接口类型?
【发布时间】:2016-02-11 23:39:59
【问题描述】:

我是 Java 新手,正在尝试学习接口的概念。我在网上看到了下面的代码。我知道该接口无法实例化。我的问题是,WatchService、Path、WatchKey 和 WatchEvent 都是接口,为什么变量可以分配给接口类型?和实例化一样吗?

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class WatchServices {

    public static void main(String[] args) throws IOException {
        WatchService ws1 = FileSystems.getDefault().newWatchService();

        Path p1 = Paths.get("/Users/justin/Desktop/Codes Netbean/JavaRandom");

        WatchKey wk1 = p1.register(ws1, ENTRY_CREATE);

        while(true){
            for(WatchEvent<?> event : wk1.pollEvents()){
                System.out.println(event.kind());
                Path file  = (Path)event.context();
                System.out.println(file);
            }
        } 
    }
}

【问题讨论】:

  • 您将编译时类型与运行时类型混淆了。声明一个变量定义了它的编译时类型——在运行时,任何兼容的引用都可以分配给它。 interface 指定引用的对象必须满足的 contact。所以WatchServiceinterface,我们知道在运行时FileSystems.newWatchService() 将返回一些实现interface 的值——但我们不知道确切的类型,因为这很可能取决于平台。有关其他示例,请参阅Collection 框架。

标签: java interface instantiation


【解决方案1】:

我会用一个例子来回答你。

假设我请你给我一个sphere。那你给我拿个沙滩球来。

球体不存在,它是一个概念,一个几何对象,而沙滩球是一个可以被视为球体的物质对象。

这大致相同,interface 通过其公开的接口定义对象的特征(可以在对象上调用的方法,假装为implement 该接口),但它本身不是物质对象.

因此,即使球体不存在,我也可以将沙滩球视为球体。实例化球体没有任何意义,因为球体无法实例化,但我可以将沙滩球视为球体。

【讨论】:

  • 我比我自己更喜欢你的答案——它简短、简单、切中要害。
【解决方案2】:

接口定义了一组可以调用但不实现它们的方法。这就是为什么你永远不能说Runnable x = new Runnable()。可以定义一个类,实现接口中的所有方法。它还必须声明它实现了该接口:

interface Runnable {
    public void run();
}

public class RandomTask implements Runnable {
    public void run() {
        System.out.println("Doing some stuff...");
    }

    public void shout() {
        System.out.println("DOING STUFF...");
    }
}

看看类是如何实现接口的。所以 RandomTask 可运行的,因此您可以在期望 Runnable 的地方分配一个 RandomTask:

Runnable x = new RandomTask();

接口告诉您该对象上必须存在哪些方法。我们知道x 必须有一个run() 方法,因为它是一个Runnable。所以我们可以说

x.run();

现在,虽然程序员知道 x 有一个 shout() 方法,但你不能再访问它了。通过将 x 分配给 Runnable,您可以将其限制为仅具有为 Runnable 定义的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多