如何引用 Java 中接口实现的类类型?
我在编写的程序中遇到了接口问题。我想创建一个接口,其方法之一接收/返回对自己对象类型的引用。就像这样:
public interface I {
? getSelf();
}
public class A implements I {
A getSelf() {
return this;
}
}
public class B implements I {
B getSelf() {
return this;
}
}
我不能在“?”处使用“I”,因为我不想返回对接口的引用,而是返回对类的引用。我搜索了一下,发现Java中没有办法“自引用”,所以我不能直接用“?”来代替。在“self”关键字或类似内容的示例中。实际上,我想出了一个类似的解决方案
public interface I<SELF> {
SELF getSelf();
}
public class A implements I<A> {
A getSelf() {
return this;
}
}
public class B implements I<B> {
B getSelf() {
return this;
}
}
,但这看起来确实是一种解决方法或类似的方法。还有其他方法吗?
I came to a problem with interfaces in a program I'm making. I want to create a interface which have one of its methods receiving/returning a reference to the type of the own object. It was something like:
public interface I {
? getSelf();
}
public class A implements I {
A getSelf() {
return this;
}
}
public class B implements I {
B getSelf() {
return this;
}
}
I can't use an "I" where it's a "?", because I don't want to return a reference to the interface, but the class. I searched and found that there are no way to "self-refer" in Java, so I can't just substitute that "?" in the example for a "self" keyword or something like this. Actually, I came up to a solution that goes like
public interface I<SELF> {
SELF getSelf();
}
public class A implements I<A> {
A getSelf() {
return this;
}
}
public class B implements I<B> {
B getSelf() {
return this;
}
}
But it really seems like a workaround or something alike. Is there another way to do so?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有一种方法可以在扩展接口时强制使用自己的类作为参数:
这甚至在编写泛型类时也有效。唯一的缺点:必须将this
转换为SELF
。正如 Andrey Makarov 在
There is a way to enforce using ones own class as a parameter when extending an interface:
This even works when writing generic classes. Only drawback: one has to castthis
toSELF
.As Andrey Makarov noted in a comment below this does not work reliably when writing generic classes.
Java 支持协变返回类型,因此这是一种选择。利用
A
和B
均派生自Object
的事实:要点是
A.getSelf()< /code> 和
B.getSelf()
是I.getSelf()
的合法重写,即使它们的返回类型不同。这是因为每个A
都可以被视为Object
,因此返回类型与该对象的返回类型兼容基函数。 (这称为“协方差”。)事实上,由于
A
和B
也已知源自I
,因此您可以替换出于同样的原因,
。I
拒绝了协方差通常是一件好事:拥有
I
类型的接口对象的人可以调用getSelf()
并获取另一个接口,这就是她需要知道的全部内容。另一方面,已经知道自己有一个A
对象的人可以调用getSelf()
并且实际上会获取另一个A
对象。附加信息可用于获取更具体的派生类型,但缺乏该信息的人仍然可以获得接口基类规定的所有内容:Java supports covariant return types, so that's one option. Take advantage of the fact that both
A
andB
are derived fromObject
:The point is that both
A.getSelf()
andB.getSelf()
are legitimate overrides ofI.getSelf()
, even though their return type is different. That's because everyA
can be treated like anObject
, and so the return type is compatible with that of the base function. (This is called "covariance".)In fact, since
A
andB
are also known to derive fromI
, you can replaceObject
byI
for the same reasons.Covariance is generally a Good Thing: Someone who has an interface object of type
I
can callgetSelf()
and get another interface, and that's all she needs to know. On the other hand, someone who already knows he has anA
object can callgetSelf()
and will actually get anotherA
object back. The additional information can be used to get a more specific derived type, but someone who lacks that information still gets everything that's prescribed by the interface base class:您可以如下编写:
然后将结果转换为您想要的类型。您现有的
A
和B
类将按原样工作。(这是返回类型协变的一个示例。Java 5 中添加了对返回类型协变的支持。这种方法会在较旧的 JDK 中给出编译错误。)
替代版本(您称其为解决方法,但实际上并不是这样) )使用泛型可以避免显式类型转换。然而,生成的代码和运行时存在隐式类型转换……除非 JIT 编译器可以将其优化掉。
AFAIK,没有更好的选择。
You can write it as follows:
and then cast the result to the type you want. Your existing
A
andB
classes will work as-is.(This is an example of return type covariance. Support for return type covariance was added in Java 5. This approach will give compilation errors in older JDKs.)
The alternative version (you call it a work-around, but it isn't really) that uses generics allows you to avoid the explicit typecast. However, there is an implicit typecast in the generated code, and at runtime ... unless the JIT compiler can optimize it away.
There are no better alternatives, AFAIK.
正如其他人所说,您可以覆盖实现类中的返回类型:
但是,我有两个“为什么”问题要问您:
1:为什么您希望接口返回实现对象?对我来说,这似乎违背了接口和继承的一般思想。您能举例说明如何使用它吗?
2:无论如何,你为什么想要这个功能?如果a.getSelf() == a,为什么不直接使用a呢?
As others have said, you can override the return type in the implementing classes:
However, I have two 'why' questions for you:
1: Why do you want an Interface to return the implementing object? It seems to run against the general ideas of interfaces and inheritance to me. Can you show an example of how this might be used?
2: In any case, why would you want this function? If a.getSelf() == a, why not just use a?