Java 从超类型方法返回子类类型 公共抽象类基类{ T方法1(){ 返回getThis(); } 公共摘要:T getThis(); } 公共类子类扩展了基类{ 公共子类getThis(){ 归还这个; } }
如果它只是一个继承级别,我可以执行上面的操作,并在调用method1()时获取子类的引用 如果我有两个层次的继承,比如Java 从超类型方法返回子类类型 公共抽象类基类{ T方法1(){ 返回getThis(); } 公共摘要:T getThis(); } 公共类子类扩展了基类{ 公共子类getThis(){ 归还这个; } },java,generics,Java,Generics,如果它只是一个继承级别,我可以执行上面的操作,并在调用method1()时获取子类的引用 如果我有两个层次的继承,比如 public abstract class BaseClass<T extends BaseClass<T>> { T method1(){ return getThis(); } public abstract T getThis(); } public class SubClass extends Ba
public abstract class BaseClass<T extends BaseClass<T>> {
T method1(){
return getThis();
}
public abstract T getThis();
}
public class SubClass extends BaseClass<SubClass> {
public SubClass getThis(){
return this;
}
}
公共抽象类子类1扩展了基类{
@凌驾
公共子类1 getThis(){
归还这个;
}
}
公共类SubClass1扩展了子类1{
}
我应该将什么更改为method1和基类,以便在调用method1时可以返回SubSubClass1类型。我不想在没有任何抑制警告的情况下执行此操作,重要的是要了解每个类型参数化类的类型参数都是自己的。特别是,它们(参数本身)不与超类或子类共享。类型参数化的子类通常会有意地与它们的超类共享类型参数值,但这是另一回事 类可以指定它们的超类,但它们不能改变它们的超类自己的继承。因此,如果
子类1
扩展了基类
,那么基类
的类子类1
的类型参数及其每个子类都是子类1
,因为只有该类才是子类1
扩展的类
BaseClass
的任何具体子类都必须实现其抽象方法getThis()
,这需要此类(例如subclass 1
)将BaseClass
的类型参数T
指定为可实例化类型(否则它无法提供返回值)。从层次结构的这一点开始,子类可以使用协变返回类型来缩小由getThis()
返回的类型,但是它们不能更改由subclass 1
指定的BaseClass
类型参数,除非它依赖于subclass 1
自己的类型参数。例如,这可以干净地编译:
public abstract class SubClass1<T extends SubClass1<T>> extends BaseClass<SubClass1<T>> {
@Override
public SubClass1<T> getThis() {
return this;
}
}
public class SubSubClass1 extends SubClass1<SubSubClass1> {
}
@HannoBinder的道具,他首先在评论中提出了协变返回类型
注意,如果这里的主要思想是使用一个类型参数来标记
基类
的哪个后代,或者至少有一个上限,那么这是错误的。在这种方法中,类型BaseClass
并不比类型SomeSubClass
本身更有意义或表达力。参数化版本的唯一区别在于更难使用。SubSubClass1
必须是实现getThis()
的版本,如下所示:
public abstract class BaseClass {
// ...
public abstract BaseClass getThis();
}
public abstract class SubClass1 extends BaseClass {
@Override
public SubClass1 getThis() {
return this;
}
}
public class SubSubClass1 extends SubClass1 {
@Override
public SubSubClass1 getThis() {
return this;
}
}
公共抽象类基类{
T方法1(){
返回getThis();
}
公共摘要:T getThis();
}
公共抽象类子类1扩展了基类{
}
公共类SubClass1扩展了子类1{
@凌驾
公共子类1 getThis(){
归还这个;
}
}
虽然我不完全清楚,但我有一个问题。在java中,一个类如何一次扩展两个类?我的意思是我们可以在一个类上使用extends关键字两次吗?@TheGuest:它不能直接扩展两个类。但是它可以实现任意多的接口。但是,如果使用&
@TheGuest查看,则可以使用多个边界限制类型参数。这是一个相当全面的解释。@TheGuest,这个例子不涉及扩展两个类的类。两个“extends”关键字中的一个适用于类型参数T
,而不是类子类1
。不确定要实现什么,但可能simple可以做到,不需要genrics。new SubSubsubClass1().method1()仍将返回子类1而不是子类1:这不是OP的意图。考虑这个片段:<代码> BaseCassBC=新子类();bc.getThis()代码>。我理解这个问题,OP想要在编译时获得类型为subsubsubclass1
的bc.getThis()
,但这里不是这样的:它是BaseClass
,很难说OP的意图是什么,但我想我的答案是他能做的最好的。我更新了一些关于为什么会这样的评论。如果他想要实现的是不可能的,那么这就是你的答案,而不是提供一个稍微不同的问题的答案。基本上,OP希望能够在很好地使用多态性的同时获得类的运行时类型。我已经更新了答案,以解释为什么OP不能得到他似乎在问的问题。我保留了提供对他来说可能可行的替代方案的部分,以及解释为什么他认为他想要的不是一个有用的目标的部分(这提高了提供的替代方案的价值)。
public abstract class BaseClass {
// ...
public abstract BaseClass getThis();
}
public abstract class SubClass1 extends BaseClass {
@Override
public SubClass1 getThis() {
return this;
}
}
public class SubSubClass1 extends SubClass1 {
@Override
public SubSubClass1 getThis() {
return this;
}
}
public abstract class BaseClass<T> {
T method1(){
return getThis();
}
public abstract T getThis();
}
public abstract class SubClass1<T> extends BaseClass<T> {
}
public class SubSubClass1 extends SubClass1<SubSubClass1> {
@Override
public SubSubClass1 getThis() {
return this;
}
}