Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何引用接口在Java中实现的类类型?_Java_Generics_Interface_Self Reference - Fatal编程技术网

如何引用接口在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;
    }
}

我感觉不到解决办法——你