Переопределение методов и полиморфизм. Полиморфизм и расширяемость.




Способность Java делать выбор метода, исходя из типа объекта во время выполнения, называется поздним связыванием.

Если объявление метода подкласса полностью, включая параметры, совпадает с объявлением метода суперкласса (порождающего класса), то метод подкласса переопределяет (overriding) метод суперкласса. Переопределение методов является основой концепции динамического связывания, реализующей полиморфизм. Когда переопределенный метод вызывается через ссылку суперкласса, Java определяет, какую версию метода вызвать, основываясь на типе объекта, на который имеется ссылка.

/* пример # 4: динамическое связывание методов: Course.java: BaseCourse.java:

OptionalCourse.java: DynDispatcher.java */

package chapt04;

public class Course {

private int id;

private String name;

public Course(int i, String n) {

id = i;

name = n;

}

public String toString() {

return "Название: " + name + "(" + id + ")";

} }

package chapt04;

public class BaseCourse extends Course {

private int idTeacher;

public BaseCourse(int i, String n, int it) {

super(i, n);

idTeacher = it;

}

public String toString() {

/* просто toString() нельзя!!!

метод будет вызывать сам себя, что

приведет к ошибке во время выполнения */

return

super.toString() + " препод.(" + idTeacher + ")";

} }

package chapt04;

public class OptionalCourse extends BaseCourse {

private boolean required;

Course

- id: int

- name: String

+ toString(): void

BaseCourse

- idTeacher: int

+ toString(): void

OptionalCourse

- required: int

+ toString(): void

public OptionalCourse(int i, String n, int it,

boolean r) {

super(i, n, it);

required = r;

}

public String toString() {

return super.toString() + " required->" + required;

} }

package chapt04;

public class DynDispatcher{

public void infoCourse(Course c) {

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

//System.out.println(c);//идентично

} }

package chapt04;

public class Runner {

public static void main(String[] args) {

DynDispatcher d = new DynDispatcher();

Course cс = new Course(7, "МА");

d.infoCourse(cc);

BaseCourse bc = new BaseCourse(71, "МП", 2531);

d.infoCourse(bc);

OptionalCourse oc =

new OptionalCourse(35, "ФА", 4128, true);

d.infoCourse(oc);

} }

выбор версии переопределенного метода производится на этапе выполнения кода.

Статические методы могут быть переопределены в подклассе, но не могут быть полиморфными, так как их вызов не затрагивает объекты. Их следует вызывать только с использованием имени класса.

Полиморфизм и расширяемость

В объектно-ориентированном программировании применение наследования предоставляет возможность расширения и дополнения программного обеспечения, имеющего сложную структуру с большим количеством классов и методов.

* пример # 5: полиморфизм: Transport.java: Bus.java: Tram.java:

RepairingCenter.java: Runner.java*/

package chapt04;

import java.util.Random;

class Transport {

public void repair() {/* пустая реализация */

} }

class Bus extends Transport {

public void repair() {

System.out.println("отремонтирован АВТОБУС");

} }

class Tram extends Transport {

public void repair() {

System.out.println("отремонтирован ТРАМВАЙ");

} }

class RepairingFactory {//шаблон Factory

public Transport getClassFromFactory(int numMode) {

switch (new Random().nextInt(numMode)) {

case 0:

return new Bus();

case 1:

return new Tram();

default:

Transport

+ repair(): void

Bus

+ repair(): void

Tram

+ repair(): void

throw new IllegalArgumentException();

// assert false; // return null;

}

} }

public class Runner {

public static void main(String[] args) {

RepairingFactory rc = new RepairingFactory();

Transport[] box = new Transport[15];

for (int i = 0; i < box.length; i++)

/* заполнение массива единицами проверямого транспорта */

box[i] = rc.getClassFromFactory(2);// 2 вида транспорта

for (Transport s: box)

s.repair();// вызов полиморфного метода

} }

Класс RepairingFactory содержит метод getClassFromFactory(int numMode), который возвращает ссылку на случайно выбранный объект подкласса класса T ransport каждый раз, когда он вызывается. Метод main() содержит массив из ссылок Transport, заполненный с помощью вызова getClassFromFactory ().

Если понадобится в дальнейшем добавить в систему, например, класс TrolleyBus, то это потребует только переопределения метода repair() и добавления одной строки в код метода getClassFromFactory(), что делает систему легко расширяемой.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: