Java泛型涉及继承和泛型的有用性扩展了我自己 [英] what the usefulness about Java generics involving inheritance and generics extends self
问题描述
我找到了泛型参数可扩展的泛型(此处).我不太了解,我怀疑一开始是错误的,但没人提出.我对此有一些疑问:
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:
- 如何使用Variant泛型,可以举个例子吗?
- 这种泛型样式的好处或效果是什么.
这是从(此处).
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;
}
现在,我们要为Man
和Woman
创建构建器.我们可以为每个实现一个生成器,复制设置name
和age
属性的方法.但是,由于Man
和Woman
从Human
继承,我们可以有一个抽象的HumanBuilder
,并使我们的WomanBuilder
和ManBuilder
继承自它.这是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屋!