【问题标题】: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?

【问题讨论】:

    标签: java polymorphism overloading


    【解决方案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());
        }
        [...]
      }
      

      【讨论】:

        猜你喜欢
        • 2010-12-07
        • 1970-01-01
        • 2022-11-24
        • 2010-09-13
        相关资源
        最近更新 更多