2015-08-21 85 views
8

重载是好的。但是如果我们考虑到我们有两个对象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将it.getId和that.name()标记为错误,并建议将它转换为((ObjectA)).getId()或((ObjectB)that).getId )。我不是在该行” T即= 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 ""; 
     } 

一般来说,我想知道,如果我的想法是可行的。如何能做到了我修复了我的错误?更重要的是,这是一个好主意吗?或者更好地简单地写入重载功能?

+11

一个典型的解决方案是,确保对象A和对象B都实现一个声明hasName和hasId方法的接口。 –

+0

鉴于'T'被擦除为'Object',因为'Object.getId()'不是实际的方法,所以上面的代码不会被编译。正如其他人所建议的那样,你需要有一个通用的接口来定义'getId'。 –

+0

@AndyTurner类型擦除不会在这里输入图片,它是纯粹的类型代数。 'T'的_upper bound_是'Object'。擦除的后果只有在运行时才会发生(编译时在某些退化的情况下,只是由于Java中擦除的具体扭曲)。 –

回答

22

这两种想法都不好,你的ObjectAObjectB类应实现一个通用接口,该接口定义了定义getId()getName()方法。

然后你就可以逃脱了一个方法:

public String getInfo(Interface o){ 
    if(o.getId()!=1) return o.getName(); 
    return ""; 
} 
+3

或者只是'getInfo()'是一个接口上的默认实现方法? – Kevin

+0

@Kevin我没有指定将单个方法放在哪里;)但是我很可能不会像这样使用默认方法(尽管目前还不清楚“case”是什么)。这段代码看起来非常平凡,可以通过一个“空白”接口轻松解决。 – Kayaman

18

您的情况是编程接口的一个很好的选择。创建接口并移动常用方法。

public String getInfo(InterfaceAB in){ 
    if(in.getId()!=1) return in.getName(); 
    return ""; 
}