【发布时间】:2015-08-21 12:06:43
【问题描述】:
重载没问题。但是如果我们认为我们有 两个对象 ObjectA 和 objectB。两者都有“id”和“name”变量。我想编写一个方法(在第三类中),它返回给定对象的名称。编写重载函数让我重复代码。这是一个很好的做法吗? 改用泛型函数不是更好吗?
所以,我知道我可以编写一个重载函数……。像这样:
public String getInfo(ObjectA o){
if(o.getId()!=1) return o.name;
return "";
}
public String getInfo(ObjectB o){
if(o.getId()!=1) return o.name;
return "";
}
而且效果很好。 但是这两个功能是一样的!唯一的区别是事实,它们需要不同类型的参数。因为它们看起来一样,是不是违反了 DRY 规则? 我尝试编写简单的通用方法,但 IDE 将 that.getId 和 that.name() 标记为错误,并建议将其转换为 ((ObjectA) that).getId() 或 ((ObjectB) that).getId() .我不是在“T that = clazz.cast(o);”行中完成了吗? 我做错了什么?
public <T> String getInfo(Class<T> clazz, Object o) {
T that = clazz.cast(o);
if (that.getId()!=1) return that.name;
return "";
}
一般来说,我想知道我的想法是否可行。我该如何解决我的错误?更重要的是,这是个好主意吗?还是直接写重载函数更好?
【问题讨论】:
-
一个典型的解决方案是确保 ObjectA 和 ObjectB 都实现声明 hasName 和 hasId 方法的接口。
-
鉴于
T被擦除为Object,以上将无法编译,因为Object.getId()不是实际方法。正如其他人所建议的那样,您需要有一个定义getId的通用接口。 -
@AndyTurner 类型擦除在这里没有进入图片,它是纯类型代数。
T的上限是Object。擦除的后果仅在运行时出现(在某些退化的情况下在编译时,但仅由于 Java 中擦除的特定扭曲)。 -
非常感谢,没想到答案这么快!两个答案都很好,而且是同时写的。真的我不知道我应该标记哪个! :)
-
请牢记single responsibility principle。如果
ObjectB的要求发生变化,它的名称被拆分为firstName和lastName怎么办?接口和ObjectA会怎样?