Java泛型涉及继承和泛型的有用性扩展了我自己 [英] what the usefulness about Java generics involving inheritance and generics extends self

查看:92
本文介绍了Java泛型涉及继承和泛型的有用性扩展了我自己的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了泛型参数可扩展的泛型(此处).我不太了解,我怀疑一开始是错误的,但没人提出.我对此有一些疑问:

I find the generics whose generics params extends itself(here). I don't understand that well.I suspect that it is wrong at the beginning, but no one put forward. I have some questions about this:

  1. 如何使用Variant泛型,可以举个例子吗?
  2. 这种泛型样式的好处或效果是什么.

这是从(此处).

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

}

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

}

谢谢!

推荐答案

我认为您是在谈论

I think you're talking about F-bounded types. I've found them very useful in situations where two hierarchies are directly correlated. The most clear case that comes to mind is the builder pattern, targeted to a hierarchy of classes. In this case, it could be of use to have a hierarchy of builders as well.

一个例子可能会引起一些启发.考虑以下(非常刻板的)层次结构:

An example might shed some light. Consider the following (very stereotyped) hierarchy:

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属性的方法.但是,由于ManWomanHuman继承,我们可以有一个抽象的HumanBuilder,并使我们的WomanBuilderManBuilder继承自它.这是F界类型派上用场的地方.

Now, we want to create builders for Man and Woman. We could implement a builder for each one, duplicating the methods to set name and age attributes. However, as Man and Woman inherit from Human, we could have an abstract HumanBuilder, and make our WomanBuilder and ManBuilder inherit from it. This is where F-bounded types come in handy.

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

这种方法节省了很多代码行,尤其是在实际的用例中.

This approach saves quite a lot of lines of code, especially in a real-world use case.

如预期的那样,使用构建器不需要任何强制转换:

As expected, using the builders does not require any casting:

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

这篇关于Java泛型涉及继承和泛型的有用性扩展了我自己的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆