为了账号安全,请及时绑定邮箱和手机立即绑定

Runnable 之类的接口有何独特之处?

Runnable 之类的接口有何独特之处?

大话西游666 2022-06-23 09:23:21
我对 java/android 中接口的理解是它们用于确保使用成员函数。例如,像Runnable一样,它确保实现的类run()使用Runnable.但是,这些功能有何独特之处?假设有另一个接口,比如Runnable只有 1 个成员函数 - 让我们称之为Passable- 它有 1 个成员函数调用pass()。这两个接口到底有什么不同(除了名称不同)?还是名称使它们与众不同?例如,Android 检测该类是否被调用Runnable,然后它会做一些不同的事情。
查看完整描述

2 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

接口不用于定义调用什么方法。

接口的主要功能之一是将 API 与实现分离。例如,这意味着任何实现 Runnable 的类都可以用于在并行线程中运行。另一种是在继承范围之外定义一个类的类型。

来自有效java的引用:

Java 编程语言提供了两种机制来定义允许多种实现的类型:接口和抽象类。这两种机制之间最明显的区别是允许抽象类包含某些方法的实现,而接口则不允许。一个更重要的区别是,要实现抽象类定义的类型,类必须是抽象类的子类。任何定义了所有必需方法并遵守通用约定的类都可以实现接口,无论该类位于类层次结构中的哪个位置。因为 Java 只允许单继承,所以对抽象类的这种限制严重限制了它们作为类型定义的使用

通过实现 Runnable 接口,您不会告诉代码应该调用 run 方法。您正在告诉代码您的类是 Runnable 的一种类型,或者从字面上看,您的类是可运行的。

如果您要使用抽象类,则可以使用一个示例用法:Plant. 现在您将使用这个类来定义植物的一些常见属性(例如它们需要土壤),然后您将创建它的子类PotatoRosemary,Dandelion

现在假设你想指出这些植物中的哪一种是可食用的,你可以创建一个中间子类EdiblePlant,它是 Plant 的子类和可食用类的超类。EdiblePlant有一个方法叫做eat(),因此你可以吃所有可食用的植物。

现在,如果您还想拥有一个类Animal及其子类DogCowPig. 您将再次必须指出哪个可以被新的中间类食用,EdibleAnimal它又会有一个eat()方法。

我想这似乎没有那么多工作,但现在如果你想拥有Human,谁吃?

你必须同时拥有Human.eat(EdibleAnimal animal);方法和Human.eat(EdiblePlant plant)方法。因为我们可以同时吃这两个。

相反,我们可以定义一个Edible具有方法的接口eat()。这种类型表明实现这种类型的类(植物和动物)实际上可以被吃掉。

既然现在我们有一个可食用的通用类型,我们可以简单地在 Human 上使用一种吃方法,Human.eat(Edible food)

由于我们现在有一个分离的接口和实现,我们不再考虑如何重构/添加新方法Human,我们只需要适当地实现Edible类型。

我建议在开始 Android 开发之前阅读 Java 的工作原理,如果你不这样做,你可以形成这些关于事物如何工作的糟糕理论模型,例如,interface determines what methods will be called当它与 Java 的实际工作原理发生冲突时,你会感到沮丧,并且不明白为什么你写的东西不像“预期的”那样工作。


查看完整回答
反对 回复 2022-06-23
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

两个接口可以具有相同的“内容”,例如相同数量的方法和匹配的方法签名。

由于名称不同,它们仍然不同。您甚至可能有同名的接口(或类!),只是在包名称上有所不同。例如,有多个名为 Pair 的不同类。

但是接口并不能确定调用了哪些方法。你编写的代码选择一个方法并调用它,而某个类实现了一个特定接口的事实只是告诉你:“好的,它是一个 Runnable,所以我可以并且可能想要调用它的 run 方法”。

你看,Java 是一种静态编译的语言。这意味着您使用类型来传达意图。您有一些代码应该由统一的,可能是多线程的上下文中的其他代码自己调用?然后您考虑将该代码放入 Runnable 中。这就是全部。


查看完整回答
反对 回复 2022-06-23
  • 2 回答
  • 0 关注
  • 144 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信