Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
НАСЛЕДОВАНИЕ И ПОЛИМОРФИЗМ.docx
Скачиваний:
6
Добавлен:
01.04.2025
Размер:
51 Кб
Скачать
☆

Перегрузка методов

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

При вызове перегруженных методов следует избегать ситуаций, когда компилятор будет не в состоянии выбрать тот или иной метод, как, например, в случае:

/* пример # 5 : вызов перегруженного метода :

DemoCD.java */

class ClassC {}

class ClassD extends ClassC{}

public class DemoCD {

static void show(ClassC obj1, ClassD obj2){

System.out.println(

" первый метод show(ClassC, ClassD)");

}

static void show(ClassD obj1, ClassC obj2){

System.out.println(

" второй метод show(ClassD, ClassC)");

}

static void show(Object obj1, Object obj2){

System.out.println(

" третий метод show(Object, Object)");

}

public static void main(String[] args) {

ClassC c = new ClassC();

ClassD d = new ClassD();

Object ob= new Object();

show(c,d);//1_первый метод

show(d,c);//2_второй метод

show(c,c);//3_третий метод

//show(d,d);// 4_ошибка компиляции

show(ob, ob);//5_третий метод

show(c,ob);//6_третий метод

show(ob,d);//7_третий метод

}

}

В первом, втором и пятом случаях передаваемые параметры в метод show() полностью совпадают с параметрами при объявлении метода. В третьем случае первый и второй методы не годятся для использования, так как одним из параметров этих методов является объект класса ClassD, а определение вызываемого метода идет вверх по цепочке наследования для параметров, поэтому в данном случае будет вызван метод с параметрами типа Object. Аналогичная ситуация возникает в шестом и седьмом случаях. В четвертом случае все три метода show() одинаково подходят для вызова, поэтому возникнет ошибка компиляции. Чтобы избежать неопределенности, следует использовать явное преобразование типов, например:

show(d,(ClassC)d);

show(d,(Object)d);

Каждый из вариантов вызовет в итоге соответствующий ему метод show().

В следующем примере экземпляр подкласса создается с помощью new, ссылка на него передается объекту суперкласса. При вызове из суперкласса соответственно вызывается метод подкласса.

/* пример # 6 : динамический вызов метода :

Dispatch.java */

class A {

void myMethod() {/* private и protected использовать нельзя, так как метод при наследовании становится недоступным*/

System.out.println("метод класса А");

}

void myMethod(int i) {

System.out.println("метод класса А с аргументом");

}

}

class B extends A {

void myMethod(int i) {

System.out.println("метод класса В с аргументом");

}

}

public class C extends B {

{

System.out.println("класс C");

}

void myMethod() {

System.out.println("метод класса С");

}

}

public class Dispatch {

public static void main(String[] args) {

A obj1 = new B();

obj1.myMethod();

A obj2 = new C();

obj2.myMethod();

obj2.myMethod(10);

}

}

В результате будет выведено:

метод класса А

класс C

метод класса С

метод класса В с аргументом

При первом обращении вызывается метод myMethod() из класса A как унаследованный. При втором обращении вызывается метод myMethod() из класса C как переопределенный. В последнем случае вызывается метод myMethod(int i) из класса B как унаследованный.