5

Программа 1методы Vararg переопределения/перегрузки спутанность

class B 
{ 
public void m1(int x) 
{ 
System.out.println("Super class"); 
} 
} 

class A extends B 
{ 
public void m1(int... x) 
{ 
System.out.println("Sub class"); 
} 
} 

class test1 
{ 
public static void main(String args[]) 
{ 
    B b1 = new B(); 
    b1.m1(10); 

    A a = new A(); 
    a.m1(10); 

    B b2 = new A(); 
    b2.m1(10); 
} 
} 

Выход:

  1. Супер класс
  2. Супер класс (Невозможно понять, почему суперкласса?!)
  3. Супер класс (Невозможно понять, почему суперкласс?!)

Программа 2:

class B 
{ 
public void m1(int... x) 
{ 
System.out.println("Super class"); 
} 
} 

class A extends B 
{ 
public void m1(int x) 
{ 
System.out.println("Sub class"); 
} 
} 

class test1 
{ 
public static void main(String args[]) 
{ 
    B b1 = new B(); 
    b1.m1(10); 

    A a = new A(); 
    a.m1(10); 

    B b2 = new A(); 
    b2.m1(10); 
} 
} 

Выход:

  1. Супер класс
  2. Sub класс (Невозможно понять, почему подкласс?!)
  3. Супер класса
  4. (Невозможно понять, почему суперкласс?!)

Привет всем, может ли кто-нибудь объяснить, есть ли переопределение/перегрузка, приводящая к выходу?

+1

Не существует переопределения в вышеуказанном виде, просто перегрузка. –

+0

Я проверил ответы, которые были полезны. Но он говорит, что мне нужно 15 репутаций для его подсчета :) –

+0

Принято !! Спасибо .. Будет держать это в виду в следующий раз и дальше –

ответ

9

Нет переопределения в вопросе вообще, только перегрузка. Переопределение будет включать A, определяющий метод с той же самой сигнатурой как соответствующий метод в B (например, если оба они имели m1(int)). Вы не делаете этого ни в одном примере, поскольку типы параметров отличаются (int против int...).

Механика разрешения подписи метода (выбор перегрузки для использования) покрывается JLS §15.12.2: Compile-Time Step 2: Determine Method Signature. Компилятор Java выберет наиболее специфический метод он может на интерфейсе определить по типу ссылки (в вашем случае, тип переменной), если есть какая-либо двусмысленность.

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

С этим фоном, причины достаточно ясны:

Программа 1:

  1. Супер класс - потому что b1 имеет тип B и B имеет только m1(int) и m1(10) соответствует его.
  2. Super class - потому что a имеет тип A; A имеет как m1(int) (от B), так и собственный m1(int...); первый - более конкретно, поэтому используется Bm1(int).
  3. Супер класс - потому что b2 имеет тип B и B имеет только m1(int).

Программа 2:

  1. Супер класс - потому что b1 имеет тип B и B имеет только m1(int...), не m1(int).
  2. Sub класс - потому что a имеет тип A и A имеет как m1(int...) (от B), а также его собственные m1(int); последний более конкретный, и поэтому используется Am1(int).
  3. Супер класс - потому что b2 имеет тип B и B имеет только m1(int...), не m1(int).
+1

Отличное объяснение тому, что происходит !! Спасибо всем за супер быстрые ответы :) –

5

В любом из ваших примеров нет переопределения, поскольку для переопределения требуется метод с тем же именем и сигнатурой, которые будут отображаться как в суперклассе, так и в подклассе. В большинстве ваших примеров нет перегрузки методов, поскольку для компилятора доступна только одна версия m1.

В первом фрагменте ссылки времени компиляции B видны только m1(int x). Ссылки на тип времени компиляции A видят оба метода, но m1(int x) по-прежнему предпочтителен, так как он лучше соответствует вызову метода (методы с varargs могут быть выбраны только при перегрузке метода, если нет других методов, которые соответствуют переданным параметрам и не содержат varargs). Поэтому метод суперкласса вызывается во всех трех случаях.

Во втором фрагменте ссылки типа времени компиляции B могут видеть только m1(int... x), поэтому этот метод вызывается в 1-м и 3-м случаях. Ссылки типа времени компиляции A видят оба метода, и на этот раз m1(int x) является предпочтительным, поэтому метод подкласса вызывается для второго случая.

1

Сначала позвольте мне объяснить, что такое vararg, который поможет мне лучше ответить на ваш вопрос. Мы используем vararg для предоставления массива примитивов в качестве аргумента метода. Обозначим elipsis (трехточечный символ) и всегда должен быть последним параметром метода. Вот почему мы не можем иметь более одного аргумента переменной в методе. Во время вызова метода мы можем либо указать значение аргумента, либо вы также можете игнорировать. Если метод перегружен переменным аргументом & конкретным типом параметра, то будет проверяться первый тип соответствия, если он будет вычислен. Если соответствующий тип параметра не найден, более высокий тип (Расширение) будет проверен, если он будет найден, затем будет вызван. Наконец, он проверит тип параметра параметра аргумента.Приоритетное порядок проверки является -

типа То же параметр> Higher тип> Переменный аргумент

Теперь, приходя на ваш вопрос.

В программе 1 - А подкласс B. Таким образом, класс А имеет как реализацию метода m1() с параметром типа INT и типа vararg. Экземпляр A вызывает реализацию подкласса метода m1(), который является тем же самым параметром. Тот же тип параметра имеет более высокий приоритет, чем vararg.

A a = new A(); 
a.m1(10); // will call higher priority m1() with same parameter type 
B b2 = new A(); 
b2.m1(10); // super class has sub class Obj.Based on dynamic disptch concept, it will always call the method declared in super class 

В программе 2 - А является подклассом разница B.Only является методы взаимозаменяемы здесь. Класс B имеет метод m1() с параметром vararg, а класс A имеет параметр типа int.

A a = new A(); 
a.m1(10); // Class A has both m1() method with int and vararg.Will call m1() method with int paramter, as it has higher priority over vararg. 

B b2 = new A(); 
b2.m1(10); // Storing sub class reference into super class. Dynamic dyspatch says with super class reference we can call only method declared in super class. Super class has m1() method with vararg, will be called. 

Надеюсь, это поможет.