Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.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_Inheritance_Polymorphism_Downcast - Fatal编程技术网

java中的多态方法返回类型向下转换

java中的多态方法返回类型向下转换,java,generics,inheritance,polymorphism,downcast,Java,Generics,Inheritance,Polymorphism,Downcast,所以我不知道这是否可能,我尝试过搜索它,但可能我的搜索词关闭了。基本上,我想知道,有没有一种方法可以在返回downcast对象的超类中创建泛型函数/方法 class A { public <downcasted type (in this example B if called from a B instance)> test() { return this; } } class B extends A { } B b = new B().test

所以我不知道这是否可能,我尝试过搜索它,但可能我的搜索词关闭了。基本上,我想知道,有没有一种方法可以在返回downcast对象的超类中创建泛型函数/方法

class A {
    public <downcasted type (in this example B if called from a B instance)> test() {
        return this;
    }
}

class B extends A { }

B b = new B().test()
A类{
公开考试(){
归还这个;
}
}
类B扩展了{}
B=新的B().测试()
基本上让“test()”以类型B的形式返回B实例,甚至知道函数/方法纯粹是在父类中声明的

我知道我可以强制转换这个变量,因为它有很多函数,其中一些函数可能会返回类类型的列表,等等,这很麻烦。我还意识到我可以@override B中的函数,并执行“return(B)this.super()”操作,但是包装许多函数是很繁琐的,这会使更新基类代码更加痛苦

我也知道你能做到

"class A<T extends A>"
“A类”
然后将B定义为

"class B extends A<B>"
“B类扩展了A”
但是如果你想让一个“C”扩展“B”,它就会断开

那么这种行为可能吗?如果是,它叫什么?我如何实现它

关于此行为在何处有用的一个示例是,您希望使任何基本数据结构都具有可扩展性,如扩展到oct/四叉树结构的N元树和/或添加“名称”和“属性”的扩展类或类似xml的节点

编辑: 这似乎是可行的(就linter而言),实现基本方法需要更多的工作,但据我所知,它已经得到了预期的最终结果。也就是说,当我试图运行它时,它会给我一个“找不到符号:类类型”错误:

static class D extends auto {

    final Class type = getClass();

    @SuppressWarnings("unchecked")
    public <T extends type> T test() {
        return (T)type.cast(this);
    }
}

static class E extends D { }
static class F extends E { }

static {
    D d = new D().test();
    E e = new E().test();
    F f = new F().test();
}
静态类D扩展自动{
最终类类型=getClass();
@抑制警告(“未选中”)
公共T检验(){
返回(T)类型.cast(本);
}
}
静态类E扩展了D{}
静态类F扩展了E{}
静止的{
D=新的D().测试();
E=新的E().测试();
F=新的F().测试();
}
更新 有一种更简单的方法,似乎有效:

class Alpha {

    @SuppressWarnings("unchecked")
    <T extends Alpha> T test() {
        return (T) this;
    }
}
但是,它不支持方法链接


原职 您需要
test()
返回
a
的子类型,而不是
a
本身。为此,
A
类的签名可以是:

class A<T extends A<?>> {

    @SuppressWarnings("unchecked")
    public T test() {
        return (T) this;
    }
}
现在
T
B
的一个子类,因为
test()
的返回类型是
T
,它将返回一个
B
实例。进一步的子类化可以通过相同的方式完成:

class C<T extends C<?>> extends B<T> { }
class C=new C().test();

我无法理解,您的最终目标是什么。@NareshJoshi的最终目标是创建可由许多不同子类继承的代码,同时为继承类提供看似第一类的方法。这个问题给出了其中的一些例子。这很有效,所以我不能对答案提出错误,我希望有一种方法可以让使用该类的最终用户更加透明,比如说,它在库中。如果有办法只调用B=new B().test(),那么必须调用B=new B().test()会很好,但我想没有。在您的“更新”中找到了很好的结果,我会将此标记为答案。谢谢刚刚注意到方法链接,这是不幸的:(我觉得奇怪的是,语言夸耀泛型,但它们没有实现一个方法来完成我以“非黑客”的方式描述的事情{不使用@suppressWarnings()/lose of chaining/在自动完成的“B=new a().test()通过lint检查。”})是的,这可能是因为目前没有语法从方法返回类的类型。例如,像
this test(){return this;}
这样的语法,或者当从
a
实例调用它时,它将返回
a
实例,当从
B
实例调用它时,它将返回
B
,等等。也许在未来这是可能的,但不幸的是,目前不是。
class B<T extends B<?>> extends A<T> { }
class C<T extends C<?>> extends B<T> { }
C<?> c = new C<>().test();