如何按参数类型选择重载方法?

Posted

技术标签:

【中文标题】如何按参数类型选择重载方法?【英文标题】:How to choose overloaded method by argument type? 【发布时间】:2019-05-13 15:08:03 【问题描述】:

我正在尝试根据参数类型重载我的方法:

FieldError 扩展ObjectError。

private String getMessage(final FieldError fieldError) 
    return String.format("%s %s", fieldError.getField(), fieldError.getDefaultMessage());


private String getMessage(final ObjectError objectError) 
    return objectError.getDefaultMessage();

现在,如果我有一个List<ObjectError> 并为该List 的元素调用上述方法,无论List 上的元素是哪种类型(ObjectErrorFieldError),getMessage(final ObjectError objectError) 将始终被调用。

List<ObjectError> errors;
getMessage(errors.get(0));

为什么会这样?如果它只是它的工作原理,有没有机会不使用if's 和instanceof's?

【问题讨论】:

【参考方案1】:

方法重载决议在编译时执行,此时只有编译时类型是已知的。因此,传递给方法调用的参数的编译时类型决定了选择哪个重载方法。

由于您将List&lt;ObjectError&gt; 的元素传递给方法调用,因此始终选择String getMessage(final ObjectError objectError),并且存储在List 中的实例的运行时类型没有任何区别。

解决问题的一种方法是将getMessage() 方法移至ObjectError 类,并在FieldError 子类中覆盖它。

代替

getMessage(errors.get(0))

你会打电话的

errors.get(0).getMessage()

这会起作用,因为方法覆盖是在运行时解决的。

【讨论】:

【参考方案2】:

errors 是一个 List,所以 errors.get(0) 是一个 ObjectError。 据此,使用 ObjectError 的方法是因为它是在编译时链接的,而不是在运行时。

为了做你想做的事,你应该在你的 ObjectError 类中添加一个getMessage() 方法,并为 FieldError 覆盖它。然后,你真的使用了多态性:

public class ObjectError 
  [...]
  public void getMessage() 
    return this.getDefaultMessage();
  
  [...]


public class FieldError 
  [...]
  @Override
  public void getMessage() 
    return String.format("%s %s", this.getField(), this.getDefaultMessage());
  
  [...]

【讨论】:

以上是关于如何按参数类型选择重载方法?的主要内容,如果未能解决你的问题,请参考以下文章

方法的重载与重写

重载中没有一个可以转换所有参数类型

面试题

方法的重载

什么是类型重载的 python 等价物?

java方法03-方法的重载