当前位置: 首页 > 面试题库 >

实际上,如何使接口实例方法仅接受相同类的参数?

师成弘
2023-03-14
问题内容

该SO讨论提出以下惯用法:

public interface IComparable<T extends IComparable<T>> {
    int compare(T t);
}

然后允许:

public class Foo implements IComparable<Foo> {
    public int compare(Foo foo) {
        return 0;
    }
}

但是,此惯用语不仅允许以上内容,而且还可以编译以下代码:

class A implements IComparable<A> {
    public int compare(A a) {return 0;}
}

public class Foo implements IComparable<A> {

    public int compare(A a) {
        return 0;
    }
}

因此(除非我误解了一些东西),与不那么戏剧性的相比,原始成语并没有买更多的东西:

public interface IComparesWith<T> {
    int compare(T t);
}

public class A implements IComparesWith<A> {
    public int compare(A a) {...}
}

那么,有没有一种方法可以真正地声明一个接口,以便任何声明要实现的类都具有与自己的类的对象进行比较的方法,而没有上述任何漏洞?

我显然不能将以上内容发表为评论,因此我创建了一个新帖子。


问题答案:

你是正确的:这个成语并 不能 阻止比较不同类的类。它所做的只是确保比较对象也实现相同的接口。如果只需要比较相同的类型,则可以由实现类强制实施。

您所说的“ 漏洞 ”就是我所谓的“ 故意做您不想做的事情 ”。

__如果需要* 这种行为,可以将 Foo 对象与 A 对象进行比较。 *

这是一个功能,而不是漏洞。

如果您希望 Foo 与其他 Foos 具有可比性,则应定义 Foo 来实现IComparable<Foo>

如果您 希望 FooA 相当,那么您 不应 定义 Foo
来实现IComaparable<A>。除非有人试图故意编写破损的代码,否则为什么有人会这样做呢?

@caskey已提供您问题的实际答案:

不,您不能使用Java中的接口来完成您想做的事情。[您必须使用类来完成。

您错过了一件事:

因此(除非我误解了一些东西),与不那么戏剧性的相比,原始成语并没有买更多的东西:

public interface IComparable<T>

原来的成语 买你的东西。它强制比较对象 必须 实现 IComparable
。不太生动的示例将允许您无限制地将实现类与任何对象进行比较。所以…编译器将允许您将Long,或InputStream,或LinkedHashSet<Byte[]>或任何其他内容指定为类型参数

当您以这种方式看待它时,很容易看出为什么这种习语如此普遍。



 类似资料:
  • 问题内容: 我想使用这样的接口: 我用代表语音识别结果的不同类型的对象来实现它。 我的想法是,我只希望比较相同类型的结果。也就是说,如果我创建一个实现的类,我希望方法签名变为: 我觉得我的界面存在设计缺陷,因为到目前为止,我对cloneWithConfidence和返回ResultItem的其他方法的结果使用了非常难看的转换。 有没有更好的办法? 问题答案: 有一个经常见到的成语如下:

  • 问题内容: 此代码完美地工作。方法test()适用于两个接口。幕后到底发生了什么?在实际情况下,此功能有何用处? 问题答案: 因为它是一个接口,所以不会造成任何危害。通过实现和,您基本上是在为您的课程使用蓝图。双方并说,应实施一个名为方法 您的类实现了该方法,因此接口已完成其工作。 基本上,您的班级在说:“哦,我需要因为接口而实现”,然后您就实现了。然后您的班级说:“哦,嘿,由于接口我需要再次实现

  • 问题内容: 我有以下类和接口: 我想创建一个方法,其中参数需要为BasicObject类型并实现CodeObject。我尝试了以下代码,但不能保证clazz是实现CodeObject的类。 我想做这样的事情,但不能编译: 问题答案: 您的模式类必须扩展和扩展/实现(实际上是一个接口)。您可以使用方法签名的通配符定义中声明的多个类来执行此操作,如下所示: 请注意,如果您通过以下任何一种方式进行操作,

  • 我有以下类和接口: 我想创建一个方法,其中参数需要是BasicObject类型,并实现CodeObject。我尝试了以下代码,但它不能保证clazz是一个实现CodeObject的类。 我想做这样的事情,但它无法编译:

  • 问题内容: 假设我必须实现在两个不同的包中声明的两个不同的接口(在两个不同的独立项目中)。 我有包装 并包装 在我的包里 如何处理这种情况? 问题答案: 正如常见问题解答所提到的 其他语言的经验告诉我们,使用具有相同名称但签名不同的多种方法有时会很有用,但在实践中也可能会造成混淆和脆弱。 在Go的类型系统中,仅按名称进行匹配并要求类型一致是简化的主要决定 。 在您的情况下,您将满足两个接口。 您可

  • 问题内容: 说我有两个结构: 我希望他们都实现接口A: 像这样对First和Second结构都实现似乎是多余的: 有没有一种方法可以为实现接口A的所有结构提供一个实现?像这样的东西,但似乎不起作用: 谢谢! 问题答案: 不,您不能, 但是 您可以创建一个基本类型,然后将其嵌入到您的2结构中,因此只需要一个基本类型的实现即可: 用法: 操场上的完整例子 嵌入文件