Leo*_*ele 19 java generics interface self-reference
我遇到了我正在制作的程序中的接口问题.我想创建一个接口,它的一个方法接收/返回对自己对象类型的引用.它是这样的:
public interface I {
? getSelf();
}
public class A implements I {
A getSelf() {
return this;
}
}
public class B implements I {
B getSelf() {
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
我不能使用"I",它是"?",因为我不想返回对接口的引用,而是类.我搜索并发现Java中没有办法"自我引用",所以我不能只用"?"来代替它.在"自"关键字的示例中或类似的东西.实际上,我找到了一个类似的解决方案
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;
}
}
Run Code Online (Sandbox Code Playgroud)
但它看起来似乎是一种解决方法或类似的东西.还有另一种方法吗?
Pat*_*ker 13
在扩展接口时,有一种方法可以强制使用自己的类作为参数:
interface I<SELF extends I<SELF>> {
SELF getSelf();
}
class A implements I<A> {
A getSelf() {
return this;
}
}
class B implements I<A> { // illegal: Bound mismatch
A getSelf() {
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
这甚至在编写泛型类时起作用.唯一的缺点:一是有投this来SELF.
正如安德烈·马卡罗夫在注意以下评论这并不能可靠地工作编写泛型类时.
class A<SELF extends A<SELF>> {
SELF getSelf() {
return (SELF)this;
}
}
class C extends A<B> {} // Does not fail.
// C myC = new C();
// B myB = myC.getSelf(); // <-- ClassCastException
Run Code Online (Sandbox Code Playgroud)
Java支持协变返回类型,因此这是一个选项.充分利用的事实,即A与B衍生自Object:
public interface I {
Object getSelf(); // or I, see below
}
public class A implements I {
A getSelf() { return this; }
}
public class B implements I {
B getSelf() { return this; }
}
Run Code Online (Sandbox Code Playgroud)
问题的关键是,无论A.getSelf()和B.getSelf()是合法的覆盖I.getSelf(),即使他们的返回类型是不同的.这是因为每一个A可以治疗一样的Object,所以返回类型兼容与基础功能.(这称为"协方差".)
事实上,自从A和B也被从推导I,可以替代Object由I出于同样的原因.
协方差通常是一件好事:拥有类型接口对象的人I可以调用getSelf()并获得另一个接口,这就是她需要知道的全部内容.另一方面,已经知道他有A对象的人可以打电话,getSelf()并且实际上会得到另一个A对象.附加信息可用于获取更具体的派生类型,但缺少该信息的人仍可获得接口基类规定的所有内容:
I x = new A();
A y = new A();
I a = x.foo(); // generic
A b = y.foo(); // we have more information, but b also "is-an" I
A c = (A)x.foo(); // "cheating" (we know the actual type)
Run Code Online (Sandbox Code Playgroud)