2013-05-12 3 views
1

Если java имеет значение pass-by-value, и это значение является адресом памяти для фактического типа, тогда почему перегруженный метод, который называется get, определяется ссылочным/объявленным типом?Почему литье определяет, какой перегруженный метод вызывается?

class Boss { 

    void test(Object o){ 
    System.out.println("object"); 
    } 

    void test(Boss b){ 
    System.out.println("boss"); 
    } 

    public static void main(String[] args) { 
    Boss b = new Boss(); 
    b.test((Object)b); //prints out object, why? 
    } 

} 
+0

Что еще нужно определить, какой метод вызывается? Результатом приведения является ссылка типа 'Object' в отношении JVM. – 11684

+0

Значение, которое передается, что является адресом памяти для объекта Boss. Поэтому я бы ожидал, что фактический тип определит, какой метод вызывается. –

+0

http://stackoverflow.com/questions/2006448/java-method-call-overloading-logic - первый связанный с этим вопрос, Джон тарелочкам ответ ... – zch

ответ

3

Динамическое связывание применяется к объекту, на который вызывается метод, а не по его параметрам и перегрузке метода.

В этом случае метод определяется во время компиляции, чтобы быть недействительным тест (Object о), потому что это перегрузка, которая соответствует типам аргументов.

Во время выполнения, реализация test(Object o) выбирается на основе объекта, на котором он называется. В этом случае это реализация в Boss.

В качестве примера, скажем, вы уже сделали это:

class Director extends Boss { ... }. 

Boss d = new Director(); 
Boss b = new Boss; 
d.test((Object)b); 

Тогда в терминах перегрузки методы, выбранный метод во время компиляции все равно будет test(Object o). Во время выполнения реализация может быть в Режиссере, поскольку d ссылается на Директора.

+0

Ух ... хорошо, я расстроен попыткой изменить свой ответ, поэтому я просто удалил его полностью. Если перегруженный метод, который будет использоваться определяется во время компиляции, то как вы объясните, когда компилятор определяет метод, который будет использоваться в суперкласса? Но затем изменяет метод, который будет использоваться во время выполнения на основе фактического типа. Например, если был суперкласс SuperBoss с теми же методами, а затем был следующим: 'SuperBoss b = new Boss();' 'b.test ((Object) b);' –

+0

О, вы Знаешь что? Игнорируйте мой предыдущий комментарий. Вы ответили уже отлично :) Спасибо! –

2

Перегрузка определяется во время компиляции, то есть компилятор решает, какой метод должен выполняться во время компиляции, независимо от объекта, который будет передан ему во время выполнения. И поскольку вы передаете ссылочную переменную Object и не Boss, хотя объект имеет Boss, он выполняет перегруженный void test(Object b) метод.

Смежные вопросы