[英]what the usefulness about Java generics involving inheritance and generics extends self
我想你在谈论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;
}
现在,我们想为Man
和Woman
创建建设者。 我们可以为每个构建器实现构建器,复制方法以设置name
和age
属性。 然而,当Man
和Woman
继承Human
,我们可以拥有一个抽象的HumanBuilder
,并使我们的WomanBuilder
和ManBuilder
继承它。 这就是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();
}
}
关于实用性,我个人并没有真正看到任何有用的东西。 这是不必要的复杂,可能会被重构为更具可读性的东西。
考虑以下示例。 您需要编写一个算法,该算法采用任何类型T
的Iterable
并返回这些对象的最小值。 要定义类型T
相对顺序,您需要通过T
传递Comparator
,或者作为替代方法,要求类型T
extends Comparable<T>
。 这是方便的替代方法,因为许多内置类型(如String
, Integer
等)已经可以。
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.