2

我总是想知道如何仅仅通过实现一个接口,子类就获得了这种行为。例如,如果我实现 Runnable 接口,我的子类开始表现为线程,但如果我实现接口 Runnable 中定义的所有方法但不写“实现 Runnable”,子类不会表现为线程。与 EventListeners 相同。请帮助我理解这种行为。

4

7 回答 7

2

通过实现接口 I,您声明对象“是”I,并且它将包含此接口定义的所有方法。如果你只是实现了接口 I 的方法,而不是通过一个 implement 语句来声明它,编译器将无法确定你的类“是”I,你将无法将它用作我型。

于 2013-06-03T09:52:51.937 回答
1

当您实现时,Runnable您的类不会成为线程并且不会以线程的形式开始行为。但是,如果您的类实现Runnable了您可以在线程上下文中运行它:

class MyClass1 implements Runnable {
    public void run() {
        // this stuff will run in thread when thread's start() method is called
    }
}

new Thread(new MyClass1()).start();

但是java是强类型语言。您可以像这样创建类:

class MyClass2 {
    public void run() {
        // this stuff will run in thread when thread's start() method is called
    }
}

但它不会Runnable。因此,您不能只将其发送到线程:

new Thread(new MyClass2()).start();

在这种情况下,您将收到编译错误。编译器无法知道您的类确实实现了看起来像在Runnable. 您必须声明这一点(如第一种情况)。

于 2013-06-03T09:54:50.453 回答
1

ARunnable只允许你的类在线程中运行。您仍然需要例如 ajava.util.concurrent.Executor在实际线程中实际运行它。

但是,您可以extend Thread调用Thread.start().

要真正从实现接口中获得行为,您需要第二个对象检查类路径以查找使用反射实现接口的类,然后对该类执行某些操作。

于 2013-06-03T09:55:55.420 回答
1

不,Runnable与表现得像线程无关。它只包含一个简单的、简单的、无效的 null 方法,称为“run”。

不指定implements Runnable只会使您的对象不是该Runnable类型的实例,这意味着您将无法将其传递给需要Runnable. 这只是类型安全的问题。您调用的方法也可以接受Objectrun使用反射调用,具有完全相同的行为。

于 2013-06-03T09:52:00.850 回答
0

你的问题有两个方面:

  1. 接口作为契约:接口将行为契约强加给实现它的类。例如,如果Car是一个带有一些抽象定义汽车的方法的接口,那么任何实现Car接口的类都必须定义汽车的方法。您可以自由地实际实施该行为。
  2. Runnable作为线程的类比是不正确的。使Runnable类充当线程的是Thread class. Runnable只是指定一个类作为线程的契约。检查这篇文章
于 2013-06-03T10:00:13.867 回答
0

这不是子类化行为。为了使用子类行为,您需要扩展类。

Wrt 接口这些只是由类实现的模板/合同。为了让runnable工作,调用程序需要实例化一个线程,当线程启动时,它将调用你的类实现的run方法。

于 2013-06-03T10:00:23.027 回答
0

我总是想知道如何仅仅通过实现一个接口,子类就获得了这种行为。

它不会“获得”任何“行为”。子类提供行为。实现接口所做的是提供编译时类型签名,以便您可以使用指定接口的子类。

于 2013-06-03T10:31:00.823 回答