【问题标题】:Define generic Type of parent class method depending on subclass Type in Java根据Java中的子类类型定义父类方法的泛型类型
【发布时间】:2014-01-05 12:32:00
【问题描述】:

是否可以根据子类 Type 动态地将 T 标识为返回类型? 我想要以下内容:

public class Parent {
        public <T extends Parent> T foo() {
                return (T)this;
        }
}

public class Child extends Parent {
        public void childMethod() {
                System.out.println("childMethod called");
        }
}

然后调用:

Child child = new Child();
child.foo().childMethod();

没有像这样定义类型:

Child child = new Child();
child.foo().<Child>childMethod(); // compiles fine

提前致谢!

【问题讨论】:

  • Child extends Parent,对吧?
  • 应该Child 扩展Parent
  • 对,我已经编辑了代码。谢谢! :)
  • @chaplean 这样做的目的是什么:child.foo().childMethod()?相同的结果将是 child.childMethod()。
  • 只是为了能够编写内联语句。

标签: java generics subclassing


【解决方案1】:

你想要这个:

public class Parent<T extends Parent<T>> {
    public T foo() {
        return (T)this;
    }
}

public class Child extends Parent<Child> {
    public void childMethod() {
        System.out.println("childMethod called");
    }
}

Child child = new Child();
child.foo().childMethod(); // compiles

【讨论】:

  • 更简单:public class Parent { }, class Child extends Parent { } 和 main : Parent instance = new Parent();
  • @solvator 否。您的代码会在绑定中生成原始类型 Parent,这是非常不可取的
  • 啊,是的,没注意到..如果没有继承,它会起作用
  • @Bohemian 为什么你使用 > 而不是
  • @solvator 我已经在上面的评论中回答了这个问题,但又来了……如果你给 Parent 一个通用参数,每次使用它都应该有参数,否则你会得到一个 raw 类型(一个没有被赋予参数的类型。虽然它看起来像无限递归,Parent&lt;T extends Parent&lt;T&gt;&gt; 是你如何指定一个泛型绑定到一个子类同时避免使用原始类型。使用原始类型时,所有通用信息都会从类中删除(几乎但不完全是,就像它的 Parent&lt;Object&gt;
【解决方案2】:

在Java 类型系统中Parent 不可能引用this 的确切类。但是,它可以有一个类型参数(比如T),子类可以将其指定为它们自己或其他类型(无论它们想要什么),并使用抽象方法来委派获取该类型实例的任务T 到子类。

public abstract class Parent<T> {
    // the implementer is responsible for how to get an instance of T
    public abstract T getT();
    // in this case, foo() is kind of redundant
    public T foo() {
        return getT();
    }
}

public class Child extends Parent<Child> {
    public Child getT() {
        return this;
    }
    public void childMethod() {
        System.out.println("childMethod called");
    }
}

Child child = new Child();
child.foo().childMethod(); // compiles

【讨论】:

    猜你喜欢
    • 2013-05-02
    • 2022-10-14
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    • 2021-02-16
    • 2011-05-11
    • 2019-12-28
    • 1970-01-01
    相关资源
    最近更新 更多