Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Практикум по объектно-ориентированному программированию..pdf
Скачиваний:
17
Добавлен:
05.02.2023
Размер:
3.39 Mб
Скачать

34

Следовательно, любой объект, обозначаемый полиморфным именем, может по-своему реагировать на некий общий набор операций.

Здесь действует принцип «Один интерфейс – много методов». Благодаря полиморфизму, программы становятся менее сложными, так как для определения и выполнения однотипных действий служит единый интерфейс. Такой единый интерфейс применяется пользователем или программистом к объектам разного типа, а выбор конкретного метода для реализации соответствующей команды осуществляется компьютером в соответствии с типом объекта, для которого выполняется команда. Пожалуй, полиморфизм – это лучшее, что есть в объ- ектно-ориентированном программировании.

· · · · · · · · · · · · · · · · · · · · · · · · ·

 

Выводы · · · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

При правильном применении полиморфизм, инкапсуляция и наследование комбинируются так, что создают некую среду программирования, которая обеспечивает намного более устойчивые масштабируемые программы.

1.Удачно спроектированная иерархия классов является базисом для повторного используемого кода.

2.Инкапсуляция позволяет реализациям мигрировать из проекта в проект без разрушения кода, который зависит от public-интерфейса классов.

3.Полиморфизм позволяет создавать ясный, хорошо модифицируемый и

читабельный код.

Хотя принципы объектно-ориентированного программирования были рассмотрены по отдельности, работают они вместе и практически не существуют отдельно друг от друга.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

1.9 Переопределение методов

Кроме перегрузки существует также переопределение методов (overriding). Подкласс наследует все переменные и методы (кроме переменных и методов с модификатором доступа private) из суперкласса (ближайшего родителя и всех предков). Подкласс может использовать унаследованные поля и методы в соответствии с тем, как они были определены.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Изменить работу любого из методов, унаследованных от класса-предка, класс-потомок может, описав новый метод с точно

35

таким же именем и параметрами. Это называется переопределе-

нием.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Замещение происходит, когда класс-потомок (подкласс) определяет неко-

торый метод, который уже есть в родительском классе (суперклассе), таким об-

разом новый метод заменяет метод суперкласса. У нового метода подкласса

должны быть те же параметры или сигнатура, тип возвращаемого результата, что

и у метода родительского класса.

Начинается такой метод с аннотации @Override.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Аннотации не являются программными конструкциями. Они

не влияют на результат работы программы. Используются они толь-

ко на этапе компиляции, после компиляции уничтожаются и не ис-

пользуются при выполнении.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Аннотация @Override не обязательна, но стоит ее иметь. В этом случае

компилятор получает возможность проверить, что вы переопределили метод, а

не написали новый. Таким образом можно избежать некоторых ошибок из-за не-

внимательности. Аннотации появились только в версии Java 1.5, и более ранние

версии их не поддерживают. Всегда используйте аннотацию @Override, когда

вы пытаетесь переопределить метод суперкласса.

· · · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Например, в классе Student мы переопределили метод toString(). Переопределим его и для класса-наследника GraduateStudent.

@Override

public String toString() {

return "ДИПЛОМНИК: " + super.toString() + " за ВКР: " + thesis;

}

super.toString() – это вызов переопределенного метода toString() в классе Student.

Создав объект класса GraduateStudent, вызовем этот метод.

GraduateStudent s4 = new GraduateStudent("Иванов",3,"Автоматизированное тестирование");

36

Далее выведем информацию о студентах на консоль (рис. 1.12).

Рис. 1.12 – Вызов переопределенного метода toString()

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

· · · · · · · · · · · · · · · · · · · · · · · · ·

 

Выводы · · · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Таким образом, можно выделить основные тезисы:

Переопределение метода происходит только тогда, когда имена и сигнатуры типов этих двух методов идентичны. Если это не так, то оба метода просто перегружены.

Поля нельзя переопределить, их можно только скрыть.

Если пометить метод модификатором final, то метод не может быть переопределен.

Переопределенные методы позволяют поддерживать полиморфизм времени выполнения.

·· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

1.10 Подстановка

Подкласс обладает всеми полями и методами своего суперкласса вслед-

ствие наследования. Это означает, что объект подкласса может делать то, что

может делать объект суперкласса. В результате мы можем заменить объектом

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

нием или подстановкой.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Принцип подстановки Барбары Лисков – специфичное опреде-

ление подтипа в объектно-ориентированном программировании.

Идея Лисков о «подтипе» дает определение понятия замещения: если

S является подтипом T, тогда объекты типа T в программе могут быть

замещены объектами типа S без каких-либо изменений желательных

свойств этой программы [3].

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

37

Так, в нашем примере классов GraduateStudent является подклассом Student. То есть можно сказать, что GraduateStudent «is-a» «является» Student (а в действительности он «является большим, чем Student»). Соотношение подкласс – суперкласс выражает так называемое соотношение «is-a» (является), которое обычно используется без перевода. С помощью подстановки можно создать объект класса GraduateStudent и присвоить его значение Student (объекту суперкласса):

Student sG=new GraduateStudent("Васильев", 4, "Разработка веб-приложения");

Теперь можно вызывать все методы, определенные в классе Student, для ссылки на sG (который все еще представляет объект GraduateStudent), например, sG.getName() и sG.getMark(). Это возможно потому, что объект подкласса обладает всеми свойствами суперкласса. Однако невозможно вызывать методы, определенные в классе GraduateStudent, для ссылки на sG, например, sG.getGPA(). Это происходит потому, что sG – это ссылка на класс Student, который не знает о методах, определенных в классе GraduateStu-dent. sG – это ссылка на класс Student, но содержит объект подкласса GraduateStudent. Ссылка на sG, однако, сохраняет внутреннюю идентичность. В нашем примере подкласс GraduateStudent переопределяет метод toString(). sG.toString() вызываeт переопределенные версии из подкласса GraduateStudent вместо версий, определенных в Student (рис. 1.13):

System.out.println(sG.toString());

Рис. 1.13 – Вызов переопределенного метода toString()

Это происходит потому, что фактически объект sG содержит внутри объ-

ект GraduateStudent.

 

· · · · · · · · · · · · · · · · · · · · · · · · ·

Выводы · · · · · · · · · · · · · · · · · · · · · · · · ·

1. Объекты суперкласса могут быть замещены объектами подкласса.