如下所示在Java接口中重载方法是否正确。然后使用子类中所需的方法?如果不是,有没有更好的方法来做,请善意。
interface IEmployees{
public List<String> getEmployees(List<String> employees, List<String> departments);
public List<String> getEmployees(List<String> employees, String name);
}
class EmployeesByDept implements IEmployees{
public List<String> getEmployees(List<String> employees, List<String> departments){
// select employees belonging to depts in list and return.
}
public List<String> getEmployees(List<String> employees, String name){
throw new UnsupportedOperationException();
}
}
class EmployeesByName implements IEmployees{
public List<String> getEmployees(List<String> employees, List<String> departments){
throw new UnsupportedOperationException();
}
public List<String> getEmployees(List<String> employees, String name){
// select employees with name in list and return.
}
}
答案 0 :(得分:2)
在我看来,重载接口这种方式并不是一个好主意,因为这会在实现类中产生不必要/无用的代码。
因此我建议写2或3个不同的接口,如此
interface IEmployees {
}
interface IEmployeesByDept extends IEmployees {
public List<String> getEmployees(List<String> employees, List<String> departments);
}
interface IEmployeesByName extends IEmployees {
public List<String> getEmployees(List<String> employees, String name);
}
通过这种方式,您可以干净地实现与您的案例相匹配的界面。
答案 1 :(得分:0)
嗯,是的,不,这取决于。
一般来说,在适当的情况下,肯定存在一些案例。
在你的情况下,可能不是,你的很多问题都归结为更基本的设计问题。因此,只需阅读您的代码段,就会出现IEmployees
:
List<Employee>
的语义等价物,或但你说:
它实际上是一个员工过滤器类。它将由其他过滤器类继承,并将实现接口中的任何一个重载方法。
所以你的第一个小问题是接口名称本身。 IEmployees
在空中留下了很多东西,但是如果你把它命名为更自我记录和描述性的东西,例如IEmployeeFilter
,事情开始变得更加明显。
现在你有一个&#34;过滤器&#34;,看来你正试图有多个独立的过滤策略:
这些是单独的过滤器,并且您声明您的接口定义了过滤器,因此这些更适合组织为两个单独的子类。
首先,界面应该是所有过滤器的共同点。如何进行过滤不是常见的方面。过滤本身是。所以考虑一下:
interface IEmployeeFilter {
public List<String> getEmployees (List<String> employees);
}
现在你有一个有意义的过滤器,一个通用的方法,其他一切都到位,例如:
class EmployeeNameFilter implements IEmployeeFilter {
private String name;
public EmployeeNameFilter (String name) {
this.name = name;
}
@Override
public List<String> getEmployees (List<String> employees) {
return employees filtered appropriately
}
}
和
class EmployeeDepartmentFilter implements IEmployeeFilter {
private List<String> departments;
public EmployeeDepartmentFilter (List<String> departments) {
departments = new ArrayList<String>(departments);
}
@Override
public List<String> getEmployees (List<String> employees) {
return employees filtered appropriately
}
}
等。然后,当您准备使用其中一个时,界面始终是相同的:
List<String> employees = ...;
IEmployeeFilter filter = new EmployeeNameFilter("bob"); // or...
// IEmployeeFilter filter = new EmployeeDepartmentFilter(...);
List<String> results = filter.getEmployees(employees); // <- interface always the same
重点是,接口作为一种工具存在,使工作更轻松。当你遇到一堆实现该界面的类但它们都实现了它的不同部分的情况时,你开始打败界面的目的,并且它提供了一个很好的暗示#&# 39;需要在设计中做出根本改变。
也就是说,更通用的经验法则是:如果您的界面使您的工作更难,或者使您的代码更加复杂,那么您做错了。否则,你已做对了。
希望这是有道理的。
答案 2 :(得分:0)
接口代表合同。您将合同定义为能够满足两个要求。如果您知道,您将无法提供合同的两个部分,请根本不使用界面。
此外,我强烈怀疑你有替代方法获取这些员工名单,这是不使用接口的另一个原因。
我猜你的IEmployeesXXX
类没有状态变量。这是一个很好的指示,表明这些方法是获取和返回对象列表的实用程序方法。
您应该将其设为经典的实用工具类,即使用abstract final class
方法的static
。
以下是使用您自己的代码的示例,它变得更多更清洁:
public abstract final class Employeesutility{
public static List<String> getEmployees(List<String> employees, List<String> departments){
// select employees belonging to depts in list and return.
}
public static List<String> getEmployees(List<String> employees, String name){
// select employees with name in list and return.
}
}
我不太喜欢Utility类,我宁愿创建一个具有丰富内部表示的中间类,以及丰富的集合,它们会暴露您提出的接口方法。但对于您的用例,这可能意味着重复整个数据库(猜测你有一个),这将是愚蠢的。如果您决定创建一个真正的员工课程,请考虑一下......当您的课程变得足够大时,您将会这样做。