Рассмотрим первый пример этой главы с другого ракурса. В следующем программном коде интерфейс метода play()
изменяется в процессе его переопределения. Это означает, что мы фактически не "переопределяем" метод, а "перегружаем" его. Компилятор позволяет нам использовать перегрузку метода, не выдавая ошибку компиляции. Однако это поведение может не соответствовать нашим ожиданиям. Вот сам пример:
//: WindError.java
// Непреднамеренное изменение интерфейса
class NoteX {
public static final int
MIDDLE_C = 0, C_SHARP = 1, C_FLAT = 2;
}
class InstrumentX {
public void play(int NoteX) {
System.out.println("InstrumentX.play()");
}
}
class WindX extends InstrumentX {
// ОШИБКА! Изменяет интерфейс метода:
public void play(NoteX n) {
System.out.println("WindX.play(NoteX n)");
}
}
public class WindError {
public static void tune(InstrumentX i) {
// ...
i.play(NoteX.MIDDLE_C);
}
public static void main(String[] args) {
WindX flute = new WindX();
tune(flute); // Не желательное поведение!
}
} ///:~
```Этот пример также демонстрирует ещё одну концепцию, которая может вызвать путаницу. В классе `InstrumentX`, метод `play()` принимает целое число (`int`) с идентификатором `NoteX`. То есть, даже если `NoteX` является именем класса, его можно использовать как идентификатор без ошибки компиляции. В классе `WindX`, метод `play()` принимает объект типа `NoteX` с идентификатором `n`. Даже если бы мы использовали `play(NoteX NoteX)`, компилятор всё равно не выдал бы ошибку. Таким образом, кажется, будто бы программист намеренно переопределил метод `play()`, но тип параметра был указан некорректно. Тем не менее, компилятор считает, что программист намеренно использует "перегрузку", а не "переопределение". Обратите внимание на различие между этими двумя терминами. "Перегрузка" означает использование одного имени для различных вариантов метода; "переопределение" же означает замену существующего метода новым, который имеет тот же самый интерфейс.Если придерживаться стандартной нотации Java, то идентификатор параметра должен быть `noteX`, чтобы отличать его от имени класса.
В методе `tune`, объект `InstrumentX i` отправляет сообщение `play()` и передает член класса `NoteX` (например, `MIDDLE_C`). Поскольку `NoteX` содержит определение типа `int`, версия перегруженного метода `play()` с параметром типа `int` будет вызываться. Так как этот метод ещё не был переопределен, используется версия базового класса.
Выходные данные будут следующими:
InstrumentX.play()
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )