如何引用接口在Java中实现的类类型?
我在制作一个程序时遇到了一个接口问题。我想创建一个接口,其中一个方法接收/返回对自己对象类型的引用。有点像:如何引用接口在Java中实现的类类型?,java,generics,interface,self-reference,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; } }
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-reference”的方法,所以我不能用示例中的“?”来代替“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{
SELF-getSelf();
}
甲级公共交通工具I{
A getSelf(){
归还这个;
}
}
公共B类工具I{
B getSelf(){
归还这个;
}
}
但这似乎真的是一个解决办法或类似的东西。还有别的办法吗
我想知道是否还有其他方法可以做到这一点
你可以这样写:
public interface I {
I getSelf();
}
然后将结果强制转换为所需的类型。您现有的A
和B
类将按原样工作
(这是返回类型协方差的一个示例。Java 5中添加了对返回类型协方差的支持。这种方法将在较旧的JDK中产生编译错误。)
使用泛型的替代版本(您称之为变通方法,但实际上并非如此)允许您避免显式类型转换。但是,在生成的代码中有一个隐式类型转换,并且在运行时。。。除非JIT编译器可以对其进行优化
没有比这更好的选择了
我想知道是否还有其他方法可以做到这一点
你可以这样写:
public interface I {
I getSelf();
}
然后将结果强制转换为所需的类型。您现有的A
和B
类将按原样工作
(这是返回类型协方差的一个示例。Java 5中添加了对返回类型协方差的支持。这种方法将在较旧的JDK中产生编译错误。)
使用泛型的替代版本(您称之为变通方法,但实际上并非如此)允许您避免显式类型转换。但是,在生成的代码中有一个隐式类型转换,并且在运行时。。。除非JIT编译器可以对其进行优化
没有更好的选择了,好吧。Java支持协变返回类型,所以这是一种选择。利用
A
和B
都源自对象的事实:
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; }
}
关键是A.getSelf()
和B.getSelf()
都是I.getSelf()
的合法重写,即使它们的返回类型不同。这是因为每个A
都可以被视为对象,因此返回类型与基函数的返回类型兼容。(这称为“协方差”。)
事实上,由于A
和B
也都是从I
派生出来的,因此出于同样的原因,您可以将对象
替换为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)
Java支持协变返回类型,所以这是一种选择。利用A
和B
都源自对象的事实:
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; }
}
关键是A.getSelf()
和B.getSelf()
都是I.getSelf()
的合法重写,即使它们的返回类型不同。这是因为每个A
都可以被视为对象,因此返回类型与基函数的返回类型兼容。(这称为“协方差”。)
事实上,由于A
和B
也都是从I
派生出来的,因此出于同样的原因,您可以将对象
替换为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)
正如其他人所说,您可以覆盖实现类中的返回类型:
public interface I {
public I getSelf();
}
public class A implements I {
@Override
public A getSelf() {
return this;
}
}
但是,我有两个“为什么”问题要问你:
1:为什么希望接口返回实现对象?对我来说,这似乎违背了接口和继承的一般思想。你能举个例子说明如何使用它吗
2:无论如何,你为什么想要这个功能?如果a.getSelf()==a,为什么不像其他人所说的那样只使用a?,您可以覆盖实现类中的返回类型:
public interface I {
public I getSelf();
}
public class A implements I {
@Override
public A getSelf() {
return this;
}
}
但是,我有两个“为什么”问题要问你:
1:为什么希望接口返回实现对象?对我来说,这似乎违背了接口和继承的一般思想。你能举个例子说明如何使用它吗
2:无论如何,你为什么想要这个功能?如果a.getSelf()==a,为什么不直接使用a?在扩展接口时,有一种方法可以强制使用自己的类作为参数:
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;
}
}
在扩展接口时,有一种方法可以强制使用自己的类作为参数:
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;
}
}
我感觉不到解决办法——你