2013-08-02 2 views
3

Хотелось бы, чтобы кто-нибудь объяснил мне, как это решение было принято. Я понимаю, что перегруженная версия выбрана на основе объявленного типа, но почему при втором вызове решение было принято на основе типа времени выполнения?
Перегрузка и полиморфизм

public class Test { 
     public static void main(String[] args) { 
      Parent polymorphicInstance = new Child(); 

      TestPolymorphicCall tp = new TestPolymorphicCall(); 
      tp.doSomething(polymorphicInstance); 
      // outputs: Parent: doing something... 

      call(polymorphicInstance); 
      // outputs: Child: I'm doing something too 
     } 
     public static void call(Parent parent){ 
      parent.doSomething(); 
     } 
     public static void call(Child child){ 
      child.doSomething(); 
     } 
    } 

    public class Parent { 
     public void doSomething() { 
      System.out.println("Parent: doing something..."); 
     } 
    } 
    public class Child extends Parent{ 
     @Override 
     public void doSomething() { 
      System.out.println("Child: I'm doing something too"); 
     } 
    } 

    public class TestPolymorphicCall { 
     public void doSomething(Parent p) { 
      System.out.println("Parent: doing something..."); 
     } 
     public void doSomething(Child c) { 
      System.out.println("Child: doing something..."); 
     } 
    } 

Заранее спасибо!

ответ

4

Ваш Родитель ссылка на класс имеет в виду ребенка объект класса:

Parent polymorphicInstance = new Child(); 

Итак, когда вы передаете ссылку на метод вызова, фактический метод вызывается это один с Родитель типа параметра только. Но при вызове метода doSomething(), на родителя ссылки:

public static void call(Parent parent){ 
    parent.doSomething(); 
} 

Это будет вызывать doSomething() метод, который вы переопределение в ребенка класса.


Это классический случай полиморфизма. Предположим, у вас есть класс Форма и подкласс Круг, который переопределяет метод calculateArea(), определенный в Форма класс.

Shape circle = new Circle(); 
// This will invoke the method in SubClass. 
System.out.println(circle.calculateArea()); 

Когда вы переопределить метод суперкласса в подклассе, то фактический метод вызывается определяется во время выполнения, основываясь на том, что реальный объект ваши супер ссылки класса указывает. Это называется Dynamic Dispatch вызова метода.

+0

Спасибо, я как бы запутался в этом сложном примере, потому что методы класса TestPolymorphicCall вообще не ссылаются на ссылку аргумента. Но вы правы, независимо от перегруженной версии вызванного метода **, который выбирается на основе объявленного типа **, при работе с полиморфными типами поведение называется подтипом. –

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