Переопределение методов и полиморфизм java

Способность Java делать выбор метода, исходя из типа объекта во время выполнения, называется поздним связыванием. При вызове метода его поиск происходит сначала в данном классе, затем в суперклассе, пока метод не будет найден или не достигнут Object – суперкласс для всех классов.

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

clip_image001

Рис. 4.1. Пример реализации полиморфизма

/* пример # 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;

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);

}

}

Результат:

Название: МА(7)

Название: МП(71) препод.(2531)

Название: ФА(35) препод.(4128) required->true

Следует помнить, что при вызове toString() обращение super всегда происходит к ближайшему суперклассу. Аналогично при вызове super() в конструкторе обращение происходит к соответствующему конструктору непосредственного суперкласса.

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

Все методы Java являются виртуальными (ключевое слово virtual, как в C++, не используется).

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

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100