2015-08-06 12 views
3
public class JavaMain { 

    public static void main(String[] args) { 
     JavaA a = new JavaB(); 
     a.m1(5); 
     a.m1(new Integer(5)); 
    } 

} 

class JavaA{ 

    public void m1(Integer i){ 
     System.out.println(2); 
    } 
} 

class JavaB extends JavaA{ 

    public void m1(int i){ 
     System.out.println(1); 
    } 

} 

Выход: 2 2Autoboxing и перегрузки

По моему разумению, результат будет "1 2".

1) Когда я вызываю метод a.m1 (5) из основного метода. В соответствии с концепцией перегрузки метод класса JavaB должен выполняться. но это не будет.

Пожалуйста, помогите мне понять концепцию перегрузки + автобоксинга.

+0

Выход 2,2, я проверил его –

+0

«По моему мнению, выход будет« 1 2 ». Зачем? Что приводит вас к такому выводу? Подсказка: вы должны различать * перегрузку * и * переопределение *. Я подозреваю, что здесь проблема. –

ответ

0

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

public static void main(String[] args) { 
    JavaA a = new JavaA(); 
    JavaA b = new JavaB(); 
    a.m1(5); 
    b.m1(new Integer(5)); 
    //output will be 
    //2 
    //1 
} 

Оба объекта может выступать в качестве объекта типа JavaA из-за полиморфизм, но экземпляр может быть любым подкласс JavaA. Завышенная реализация m1 будет вызываться, когда фактический тип имеет значение JavaB. Первоначальная реализация будет вызываться, когда тип экземпляра - JavaA.

1

Решение о выборе перегруженного метода выполняется во время компиляции на основе методов, доступных для типа времени компиляции. Ваша переменная a имеет тип компиляции JavaA, а JavaA имеет только один метод m1, так что это единственный метод, который можно выбрать.

m1 из JavaB класса не может быть кандидатом, даже если тип вводного время a является JavaB.

Таким образом, вы получите выходной

2 
2 
+0

Вы правы, чтобы иметь выход '1, 2',' JavaB a = new JavaB(); 'необходимо –

5
JavaA a = new JavaB(); 
a.m1(5); 
a.m1(new Integer(5)); 
  • статического типа a İŞ JavaA
  • JavaA объявляет только один метод m1
  • , который принимает метод Integer
  • это применимый к обоим звонкам

Подпись метода разрешена на компиляция время. Компилятор рассматривает только сигнатуры, объявленные в статическом типе целевого выражения (JavaA в вашем случае).

+0

Хороший ответ, тип' a' на самом деле не является статическим. Я бы предложил немного изменить формулировку. –

+0

Что это значит? Java является статически типизированным языком, а (статическим) типом переменной 'a' является' JavaA'. –

+0

Просто '' 'переменная и может быть переназначена, поэтому тип переменной не является статичным. В вопросе тип 'a' является' JavaB' во время выполнения. Он может быть назначен экземпляру 'JavaA', и тогда тип переменной A изменится. –

0

В Java int и Integer не являются теми же типами, когда речь идет о методах переопределения. Это означает, что метод m1 от JavaB не отменяет m1 от JavaA. Вы можете проверить его с помощью аннотации @Override - здесь это просто не работает. Во время компиляции эти два метода перегружены, а не переопределяются, поэтому, когда в вашем методе main() вы хотите обрабатывать a, так как он имеет тип JavaA здесь: JavaA a = new JavaB();, тогда нет другого выбора, кроме того, что метод вызова от JavaA - полиморфизм здесь бесполезен.