Как выбрать перегруженный метод по типу аргумента? - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь перегрузить свой метод в зависимости от типа аргумента:

FieldError extends 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, независимо от того, какого типа (ObjectError или FieldError) элементы на List,
getMessage (finalObjectError objectError) всегда будет вызываться.

enter image description here

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

Почему он так себя ведет?Если это просто, как это работает, есть ли шанс не использовать if и instanceof?

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

errors является списком, поэтому errors.get(0) является ошибкой объекта.В соответствии с этим, метод, принимающий ObjectError, используется потому, что он связан во время компиляции, а не во время выполнения.

Чтобы сделать то, что вы хотите, вы должны добавить метод getMessage() в свой класс ObjectError ипереопределить его для 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());
  }
  [...]
}
0 голосов
/ 12 декабря 2018

Разрешение перегрузки метода выполняется во время компиляции, когда известен только тип времени компиляции.Следовательно, тип времени компиляции параметров, передаваемых в вызов метода, определяет, какой из перегруженных методов выбран.

Поскольку вы передаете элементы List<ObjectError> в вызов метода, String getMessage(final ObjectError objectError) всегдавыбран, и тип времени выполнения экземпляров, хранящихся в этом List, не имеет значения.

Один из способов решения вашей проблемы - переместить метод getMessage() в класс ObjectError и переопределитьэто в подклассе FieldError.

Вместо

getMessage(errors.get(0))

вы будете вызывать

errors.get(0).getMessage()

Это будет работать, поскольку переопределение метода разрешается вво время выполнения.

...