Java: 如何编写泛型方法?
Java: How do I write a generic method?
假设我有几个 Creature
sub类,并且它们每个都有某种 getGroup()
方法 returns a List<Creature>
.
我说的"some sort of".getGroup()
方法的意思是这个函数的名字在sub类之间是不一样的。例如,Wolf
成群结队旅行,因此他们有一个 getPack()
成员。 Fish
在学校出差,所以他们有.getSchool()
个会员,Humans
有getFamily()
个会员,依此类推。
.getGroup()
在Creature
中不存在,无法添加到界面中。 None 个类别可以编辑。
我正在编写一种方法来打印他们组中 Creature
的数量。我该怎么做?
本质上,我希望将这两个函数压缩成同一件事:
public void PrintSchoolSize(Fish dory) {
System.out.print(dory.getSchool().size());
}
public void PrintHiveSize(Bee bee) {
System.out.print(bee.getColony().size());
}
...进入以下函数:
public void printGroupSize( Class<? extends Creature> cree,
FunctionThatReturnsList getGroup() ) {
System.out.print(cree.getGroup().size();
}
我想我需要将第二个参数(函数指针?)传递给 void printGroupSize
。非常感谢任何帮助,谢谢!
编辑谢谢大家的帮助。这只是我试图解决的 真实 问题的简化。冗长、过于复杂的问题更难回答,所以我提出了这个更简单的场景。
唯一的答案是使用通用函数(如果存在的话)。 我实际使用的 类 没有通用接口,但它们都有一个功能,即 returns 一个列表。
你在问题中描述的内容与Java对"generic methods"的感觉没有太大关系。你可以用反射来实现它(见 Class.getMethod()),但我向你保证你真的不想去那里。
Creature
最好声明一个可能 abstract
方法 getGroup()
每个子类都会覆盖。如果您愿意,除了提供具有子类特定名称的方法之外,您还可以这样做。想要在不知道特定生物类型的情况下获取组(或其大小)的代码将调用该生物的 getGroup()
方法。那是 多态性 的应用,这似乎是您真正想要的。
如果无法将 getGroup 添加到 Creature 接口,为什么不为您的生物添加另一个接口?
public interface HasGroup {
Group getGroup();
}
这意味着您可以创建方法:
public void printGroupSize(HasGroup cree) {
System.out.print(cree.getGroup().size();
}
最简单的方法是在 Creature
接口上有一个 getGroup()
方法,并在每个子类中实现它,但似乎你不能那样做。
如果您可以修改子类,我实际上会创建一个带有 getGroupSize()
and/or getGroup()
的新接口 CreatureGroupable
。 Creature
的每个子类都应实现此接口,例如
public interface CreatureGroupable {
CreatureGroup getGroup();
}
public enum CreatureGroup {
WOLF_PACK("pack", 30),
GEES_FLOCK("flock", 20),
FISH_SCHOOL("school", 1000),
HUMAN_FAMILY("family", 4),
...
private final String name;
private final int size;
private CreatureGroup(String name, int size) {
this.name = name;
this.size = size;
}
public String getName() { return name; }
public int getSize() { return size; }
}
public class Wolf implements Creature, CreatureGroupable {
// methods from Creature, constructor, ...
public CreatureGroup getGroup() {
return CreatureGroup.WOLF_PACK;
}
这样,如果您有一个 List<Creature>
,您可以访问每个人的组并执行您必须执行的任何操作,例如
public void printGroups(List<Creature> creatures) {
for (Creature c : creatures) {
CreatureGroup group = c.getGroup();
System.out.println("A " + group.getName() +
" has roughly " group.getSize() +
" individuals.");
}
}
如果您想要更大的灵活性,您可以不使用 enum
而只使用标准的 interface
和 class
组层次结构。
感谢大家的帮助。由于我不允许编辑任何上述classes/interfaces(我只能编写外部函数),我写了以下函数
public List<? extends Creature> getGroup(Object obj) {
if(obj.getClass() == Bee.class)
return ((Bee)obj).getColony();
if(obj.getClass() == Fish.class)
return ((Fish) obj).getSchool();
/* repeat for the other classes */
return null;
}
...并在这里使用它,如下所示:
public void printGroupSize( Class<? extends Creature> cree ) {
System.out.print(getGroup(cree).size());
}
我已验证此解决方案确实有效,因为所有 get*****() 函数 return a List<Creature>
。此解决方案还显着缩小了我的代码库,并且比当前结构更易于维护。
假设我有几个 Creature
sub类,并且它们每个都有某种 getGroup()
方法 returns a List<Creature>
.
我说的"some sort of".getGroup()
方法的意思是这个函数的名字在sub类之间是不一样的。例如,Wolf
成群结队旅行,因此他们有一个 getPack()
成员。 Fish
在学校出差,所以他们有.getSchool()
个会员,Humans
有getFamily()
个会员,依此类推。
.getGroup()
在Creature
中不存在,无法添加到界面中。 None 个类别可以编辑。
我正在编写一种方法来打印他们组中 Creature
的数量。我该怎么做?
本质上,我希望将这两个函数压缩成同一件事:
public void PrintSchoolSize(Fish dory) {
System.out.print(dory.getSchool().size());
}
public void PrintHiveSize(Bee bee) {
System.out.print(bee.getColony().size());
}
...进入以下函数:
public void printGroupSize( Class<? extends Creature> cree,
FunctionThatReturnsList getGroup() ) {
System.out.print(cree.getGroup().size();
}
我想我需要将第二个参数(函数指针?)传递给 void printGroupSize
。非常感谢任何帮助,谢谢!
编辑谢谢大家的帮助。这只是我试图解决的 真实 问题的简化。冗长、过于复杂的问题更难回答,所以我提出了这个更简单的场景。
唯一的答案是使用通用函数(如果存在的话)。 我实际使用的 类 没有通用接口,但它们都有一个功能,即 returns 一个列表。
你在问题中描述的内容与Java对"generic methods"的感觉没有太大关系。你可以用反射来实现它(见 Class.getMethod()),但我向你保证你真的不想去那里。
Creature
最好声明一个可能 abstract
方法 getGroup()
每个子类都会覆盖。如果您愿意,除了提供具有子类特定名称的方法之外,您还可以这样做。想要在不知道特定生物类型的情况下获取组(或其大小)的代码将调用该生物的 getGroup()
方法。那是 多态性 的应用,这似乎是您真正想要的。
如果无法将 getGroup 添加到 Creature 接口,为什么不为您的生物添加另一个接口?
public interface HasGroup {
Group getGroup();
}
这意味着您可以创建方法:
public void printGroupSize(HasGroup cree) {
System.out.print(cree.getGroup().size();
}
最简单的方法是在 Creature
接口上有一个 getGroup()
方法,并在每个子类中实现它,但似乎你不能那样做。
如果您可以修改子类,我实际上会创建一个带有 getGroupSize()
and/or getGroup()
的新接口 CreatureGroupable
。 Creature
的每个子类都应实现此接口,例如
public interface CreatureGroupable {
CreatureGroup getGroup();
}
public enum CreatureGroup {
WOLF_PACK("pack", 30),
GEES_FLOCK("flock", 20),
FISH_SCHOOL("school", 1000),
HUMAN_FAMILY("family", 4),
...
private final String name;
private final int size;
private CreatureGroup(String name, int size) {
this.name = name;
this.size = size;
}
public String getName() { return name; }
public int getSize() { return size; }
}
public class Wolf implements Creature, CreatureGroupable {
// methods from Creature, constructor, ...
public CreatureGroup getGroup() {
return CreatureGroup.WOLF_PACK;
}
这样,如果您有一个 List<Creature>
,您可以访问每个人的组并执行您必须执行的任何操作,例如
public void printGroups(List<Creature> creatures) {
for (Creature c : creatures) {
CreatureGroup group = c.getGroup();
System.out.println("A " + group.getName() +
" has roughly " group.getSize() +
" individuals.");
}
}
如果您想要更大的灵活性,您可以不使用 enum
而只使用标准的 interface
和 class
组层次结构。
感谢大家的帮助。由于我不允许编辑任何上述classes/interfaces(我只能编写外部函数),我写了以下函数
public List<? extends Creature> getGroup(Object obj) {
if(obj.getClass() == Bee.class)
return ((Bee)obj).getColony();
if(obj.getClass() == Fish.class)
return ((Fish) obj).getSchool();
/* repeat for the other classes */
return null;
}
...并在这里使用它,如下所示:
public void printGroupSize( Class<? extends Creature> cree ) {
System.out.print(getGroup(cree).size());
}
我已验证此解决方案确实有效,因为所有 get*****() 函数 return a List<Creature>
。此解决方案还显着缩小了我的代码库,并且比当前结构更易于维护。