繁体   English   中英

关于继承和泛型的Java泛型的有用性扩展了自我

[英]what the usefulness about Java generics involving inheritance and generics extends self

我找到了泛型params扩展自己的泛型( 这里 )。 我不太了解。我怀疑一开始是错的,但没有人提出来。 我对此有一些疑问:

  1. 如何使用Variant泛型,你能举个例子吗?
  2. 这种仿制药的好处或效果是什么。

这是从( 这里 )挑选的泛型样式代码。

abstract class Base<T extends Base<T>> {

}

class Variant<T extends Variant<T>> extends Base<T> {

}

谢谢!

我想你在谈论F-bounded类型 我发现它们在两个层次结构直接相关的情况下非常有用。 想到的最明显的案例是构建器模式,它针对类的层次结构。 在这种情况下,也可以使用构建器的层次结构。

一个例子可能会有所启发。 考虑以下(非常刻板的)层次结构:

public abstract class Human {

    protected String name;

    protected int age;
}

public class Woman extends Human {

    protected String loveMovie;
}

public class Man extends Human {

    protected String soccerTeam;
}

现在,我们想为ManWoman创建建设者。 我们可以为每个构建器实现构建器,复制方法以设置nameage属性。 然而,当ManWoman继承Human ,我们可以拥有一个抽象的HumanBuilder ,并使我们的WomanBuilderManBuilder继承它。 这就是F-bound类型派上用场的地方。

Human类及其HumanBuilder如下:

public abstract class Human {

    protected String name;

    protected int age;

    public static abstract class HumanBuilder<H extends Human, 
                                              T extends HumanBuilder<H, T>> {
        protected String name;

        protected int age;

        @SuppressWarnings("unchecked")
        public T name(String name) {
            this.name = name;
            return (T) this;
        }

        @SuppressWarnings("unchecked")
        public T age(int age) {
            this.age = age;
            return (T) this;
        }

        protected void fill(H human) {
            human.name = this.name;
            human.age = this.age;
        }

        protected abstract H create();

        public final H build() {
            H human = this.create();
            this.fill(human);
            return human;
        }
    }
}

这将是Woman类及其WomanBuilder

public class Woman extends Human {

    protected String loveMovie;

    public static class WomanBuilder extends HumanBuilder<Woman, WomanBuilder> {

        protected String loveMovie;

        public WomanBuilder loveMovie(String loveMovie) {
            this.loveMovie = loveMovie;
            return this;
        }

        @Override
        protected void fill(Woman woman) {
            super.fill(woman);
            woman.loveMovie = this.loveMovie;
        }

        @Override
        protected Woman create() {
            return new Woman();
        }
    }
}

最后,这里是Man类,以及它的ManBuilder

public class Man extends Human {

    protected String soccerTeam;

    public static class ManBuilder extends HumanBuilder<Man, ManBuilder> {

        protected String soccerTeam;

        public ManBuilder soccerTeam(String soccerTeam) {
            this.soccerTeam = soccerTeam;
            return this;
        }

        @Override
        protected void fill(Man man) {
            super.fill(man);
            man.soccerTeam = this.soccerTeam;
        }

        @Override
        protected Man create() {
            return new Man();
        }
    }
}

这种方法可以节省大量代码,特别是在实际用例中。

正如预期的那样,使用构建器不需要任何铸造:

Man man = new Man.ManBuilder()
    .name("Joe")
    .age(29)
    .soccerTeam("Los Angeles Galaxy")
    .build();

Woman woman = new Woman.WomanBuilder()
    .name("Jane")
    .age(25)
    .loveMovie("Meet Joe Black")
    .build();

从你链接的代码看,Base和Variant类看起来像是返回对它们自己的类的对象的引用的方法,我猜测它类似于Singleton。

abstract class Base {
    protected abstract Base getNewInstance();
}

现在,如果你想返回Base的子类的实例,那你就不走运了。 这就是仿制药的用武之地。

class Variant<T extends Variant<T>> extends Base<T> {
    protected Base<T> getNewInstance() { 
        return new Variant(); 
    }
}

关于实用性,我个人并没有真正看到任何有用的东西。 这是不必要的复杂,可能会被重构为更具可读性的东西。

考虑以下示例。 您需要编写一个算法,该算法采用任何类型TIterable并返回这些对象的最小值。 要定义类型T相对顺序,您需要通过T传递Comparator ,或者作为替代方法,要求类型T extends Comparable<T> 这是方便的替代方法,因为许多内置类型(如StringInteger等)已经可以。

public static <T extends Comparable<T>> T min(Iterable<T> args) {
    T m = null;
    for (T arg : args)
        m = (m == null || arg.compareTo(m) < 0) ? arg : m;
    return m;
}

这并不是扩展你所谈论的形式,而是密切相关的。 例如,通用扩展本身在树结构中可能是有用的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM