java - 为什么不允许以下接口(interface)契约(Contract)?

标签 java interface

我正在考虑为 Java 提供一项新功能,但我想问一下为什么到目前为止它受到设计的限制:

public abstract class BodyPart {
    abstract public void followBodyPart(BodyPart part);
}

public class Head extends BodyPart{
     public void followBodyPart(Body body ) { //Why is this kind of implementation not allowed? 
     ...
     }
}
public class Body extends BodyPart{
     public void followBodyPart(Head head ) { //and this
     ...
     }
     public void followBodyPart(Forearm leftForearm ) { //and also this
     ...
     }
     ...
}
//Arm, Forearm, etc...

为什么 Head 中的 followBodyPart(Body body) 没有实现 BodyPart 中的 followBody?如果可以的话,优势就很明显了。

首先,IDE 将能够在其自动完成功能中提供 Body 对象作为 followBody 的参数,而不是 Head 无法跟随的任何其他 BodyParts 对象。

其次,当前版本的Body由一个函数和多个instanceof组成,可以取消。

最后,泛型在这里可以提供帮助,但不能解决问题,因为这段代码应该移植到 Java ME 设备上。

这个问题已经在我发现的不合适的论坛中提出了here

关于答案,我请你换位思考。我知道任何实现 BodyPart 的东西都应该接受 any BodyPart,但是:我想要的是能够说 Head 能够接受 A BodyPart 来跟随。

谢谢。

最佳答案

您链接的论坛帖子中也回答了这个问题..

即;接口(interface)定义函数应该能够接受任何实现了BodyPart .

通过实现Head中的函数接受子类Body ,但不是任何其他子类;你违反了那个契约(Contract)(因为它不再接受任何实现 BodyPart 的东西)。

接口(interface)通常用于提供给“外部”代码,让他们确信,无论提供哪个接口(interface)实现;他们肯定可以使用接口(interface)定义的功能。

所以如果这个外部代码得到一个BodyPart , 它知道它有一个函数 followBodyPart可以接受任何扩展 BodyPart作为论据。然而,外部代码永远不会知道它得到了Head。 (或者可以,在检查 instanceof 之后转换它)因此不知道接口(interface)函数将接受 Body .


根据要求;假设您提供了 BodyPart作为某种程序 API 的接口(interface)。在这种情况下,我不需要直接知道 BodyPart 的类型。这是。现在说我有两个;通过您的 API 中的某些函数接收,例如带有签名:public BodyPart getBody() .该方法声明它可能是一个Body我回来了;但它也可能是其他东西(事实是,我不知道!)。

根据 BodyPart界面;我可以打电话followBodyPart第一BodyPart , 并将第二个作为参数传入。然而,实际Body实现不允许这样做;我无法知道这一点。

如果你真的想让不同的类接受不同的条目;你应该从 BodyPart 中删除函数并在子类中实现它。

通过将这些子类从 API 传回;每个人都知道他们在和什么说话,以及它能做什么(例如 public Body getBody()public Head getHead() )。从那以后我有了实际的实现类,它有一个特定的 BodyPart 的实际实现。 “跟随”,这不是问题。

另一种选择是——但在你的问题中说不可能——使用泛型;在这种情况下,您可以定义一个接口(interface)声明:

public interface Accepts<T extends BodyPart> {
    public void followBodyPart(T part);
}

API 可以传回已实现的 BodyPart ,或 Accepts<Head>例如,例如。 (编辑:当我在这里写这篇文章时,我忘了记住你不能用不同的泛型类型多次实现相同的接口(interface);所以泛型接口(interface)方法需要实际的实现来封装可以实际处理调用的对象,使得一切更乱)

奖金编辑:当然你也可以制作AcceptsHead , AcceptsArm作为接口(interface)并有效地解决泛型问题:)。

我希望这次编辑能澄清为什么拥有一个通用接口(interface)(使用 BodyPart 作为参数)是一个奇怪(和坏)的想法,但只在(可能隐藏的)实现类中指定特定实现。

关于java - 为什么不允许以下接口(interface)契约(Contract)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11260426/

相关文章:

java - 创建 x 路径时遇到困难

go - 接口(interface)的泛型和非泛型使用有什么区别?

java - 为什么 Java 不允许多重继承,但允许遵循具有默认实现的多个接口(interface)

delphi - Delphi中的接口(interface)多态性

pointers - 满足接口(interface)的 Go 结构方法类型

java - 如何使用 Java 接收页面摘要?

java - 如何使用方法返回用户输入值的 double 组?

java - 是否可以从 future 的 Android 版本 (2.3.3) 中获取 C++ 库并在以前的版本 (2.1) 上使用它们?

java - android - RecyclerView - 不创建项目(跳过它)

go - 使用自定义类型实现接口(interface)而不导入包