【问题标题】:Polymorphic method return type down-casting in javajava中的多态方法返回类型向下转换
【发布时间】:2018-08-07 03:13:18
【问题描述】:

所以我不知道这是否可能我已经尝试过搜索,但可能我的搜索词已关闭。基本上我想知道,有没有办法在返回向下转换对象的超类中创建通用函数/方法。

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()

基本上让“test()”将 B 实例作为 B 类型返回,甚至知道函数/方法是纯粹在父类中声明的?

我知道我可以转换变量,但有很多函数,其中一些可能会返回类类型的列表等变得很麻烦。我也意识到我可以@override B 中的函数并执行“return (B)this.super()”的事情,但是再次包装许多函数很乏味,并且使更新基类代码更加痛苦。

我也知道你可以做到

"class A<T extends A>"

然后将B定义为

"class B extends A<B>"

但是如果你想制作一个扩展“B”的“C”,它就会中断。

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

此行为可能有用的一个示例是您希望使其可扩展的任何基本数据结构,例如您扩展为八进制/四叉树结构的 N-Ary 树和/或添加“名称”的扩展类" 和 "属性" 或类似 xml 的节点的东西。

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

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();
}

【问题讨论】:

  • 我无法理解,你的最终目标是什么。
  • @NareshJoshi 最终目标是创建可以被许多不同子类继承的代码,同时为继承类提供看似一流的方法。该问题给出了其中一些示例。

标签: java generics inheritance polymorphism downcast


【解决方案1】:

更新

有一种更简单的方法,似乎可行:

class Alpha {

    @SuppressWarnings("unchecked")
    <T extends Alpha> T test() {
        return (T) this;
    }
}
class B extends A { }

但是,它不支持方法链接。


原帖

您需要test() 来返回A 的子类型,而不是A 本身。为此,A 类的签名可能是这样的:

class A<T extends A<?>> {

    @SuppressWarnings("unchecked")
    public T test() {
        return (T) this;
    }
}

如果您创建一个扩展A 的类B,您将需要B.test() 来返回B 的实例,而无需覆盖test() 返回特定类型。然后你可以这样做:

class B<T extends B<?>> extends A<T> { }

现在TB 的子类,因为test() 的返回类型是T,所以它将返回一个B 实例。可以用同样的方式进行进一步的子类化:

class C<T extends C<?>> extends B<T> { }

这样的陈述会起作用:

C<?> c = new C<>().test();

【讨论】:

  • 这行得通,所以我不能错误地回答答案,我希望有一种方法可以使它对使用该类的最终用户更加透明,就像它在库中一样。必须调用 B> b = new B().test(),如果有办法只做 B b = new B().test(),那就太好了,但我想没有?
  • 在您的“更新”中很好地找到了我会将其标记为答案。谢谢!
  • 刚刚注意到方法链接,这很不幸:(我觉得奇怪的是语言拥有泛型,但它们没有实现一种方法来做我以“非黑客”方式描述的事情{不是在自动完成“B b = new A().test() 通过 lint 检查”中使用 @SurpressWarnings() / 失去链接 / 未指定返回类型。})
  • 是的,这可能是因为当前没有从方法返回类的类型的语法。例如,this test() { return this; } 之类的语法在从 A 实例调用时会返回 A 实例,从 B 实例调用时会返回 B 等等。也许将来有可能,但不幸的是,目前还没有。
猜你喜欢
  • 1970-01-01
  • 2013-08-19
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多