2013-08-23 2 views
0

Heres код:Может ли кто-нибудь объяснить мне этот результат полиморфизма?

class A{ 
    int data=10; 
    void show1(){ 
     System.out.println("In A="+data); 
    } 
} 

class B extends A{ 
    int data=20; 
    void show2(){ 
     System.out.println("In B="+data); 
    } 



} 


public class Overriding4 { 
    public static void main(String args[]){ 
     B b=new B(); 
     System.out.println("Data1="+b.data); 
     System.out.println("Data2="+b.data); 
     b.show1(); 
     b.show2(); 
    } 
} 

И Heres выход:

Data1=20 
Data2=20 
In A=10 
In B=20 

Выход на Data1 = 20 должно быть 10, а не 20 ... но я думаю, что я что-то здесь отсутствует. Пожалуйста, помогите мне с этим

Хорошо, спасибо за помощь, но один новое сомнение: Что бы произошло, если бы я изменил основной метод:

public static void main(String args[]){ 
      A a=new B(); 
      System.out.println("Data1="+a.data); 
      System.out.println("Data2="+a.data); 
      a.show1(); 
      a.show2(); 
     } 

Там вы идете.

+0

Почему вы думаете, что это должно быть '10'? –

+0

Зачем «Data1» должно быть 10? –

+0

Это 20, потому что вы обновляете поле так, чтобы оно использовало значение объявленного поля, а не значение поля в суперклассе. На самом деле вы должны попытаться избежать дублирования имен полей (имена полей, которые существуют в суперклассе, а также подкласс), потому что это может избежать много путаницы. –

ответ

1

Поля класса не наследуются. Обратите внимание, что у вас есть одно и то же поле int data в обоих классах A и B. Это называется Hiding.

0

Поскольку вы переопределили переменную данных в классе B, она напечатает последнее значение. Поскольку вы переоценили «данные» как 20 в классе B, это то, что он покажет.

1

Для того, чтобы «чувствовать» силу полиморфизма мы должны изменить ваш код немного:

class A { 

    int data=10; 
    void show(){ 
     System.out.println("In A="+data); 
    } 
} 

class B extends A { 

    int data=20; 

    @Override 
    void show(){ 
     System.out.println("In B="+data); 
    } 

    public static void main(String args[]){ 
     A a = new A(); 
     A b = new B(); 
     a.show(); 
     b.show(); 
    } 
} 

Теперь вы можете увидеть, что оба a и b объявлены типа A - но назначение - вот что делает разницу. Кроме того, мы можем создать массив типа А и вместит его с объектами обоих типов (A а также B):

A[] arr = new A[3]; 

// давайте добавим некоторые вещи;

arr[0] = new A(); 
arr[1] = new B(); 
arr[2] = new A(); 

И теперь это легко увидеть, как красиво полиморфизма worksL

for (int i=0; i<arr.length; i++){ 
    arr[i].show(); 
} 

напечатает последний цикл:

In A 10 
In B 20 
In A 10 

Все мы знаем, что массив содержит объекты, которые являются суб- типы A - и мы можем рассчитывать на каждый объект для вызова «правильного» метода show(). Это полиморфизм!

1
Within a class, a field that has the same name as a field in the superclass hides 
the superclass's field, even if their types are different. 

Это можно найти в Hiding fields

Следовательно, он печатает 20.

0

Объект класса B имеет два поля, как назвали data, но, как предполагает Луиджи, один из тех, кто скрыт , Если вы хотите, чтобы получить его обратно, используйте бросок:

public class Overriding4 { 
    public static void main(String args[]){ 
     B b=new B(); 
     System.out.println("Data1="+((A)b).data); // like this 
     System.out.println("Data2="+b.data); 
     b.show1(); 
     b.show2(); 
    } 
} 

производит:

Data1=10 
Data2=20 
In A=10 
In B=20 

P.S.вы можете использовать литой с обеих сторон назначения:

public class Overriding4 { 
    public static void main(String args[]){ 
     B b=new B(); 
     ((A)b).data *= 10; 
     System.out.println("Data1="+((A)b).data); 
     System.out.println("Data2="+b.data); 
     b.show1(); 
     b.show2(); 
    } 
} 

Data1=100 
Data2=20 
In A=100 
In B=20 

PPS. Я разместил это, чтобы показать вам, как работает язык, но в целом это не хорошая идея иметь общедоступные поля в классах, которые другие классы могут читать и писать напрямую. См Why use getters and setters?

0

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

System.out.println("Data1="+b.data); 
System.out.println("Data2="+b.data); 

Это может быть полезно визуализировать объект, как это:

A { 
    [A.data = 10]; <-- this is overridden and cannot be accessed directly 
    show1() => 10; 
    B { 
    B.data => 20; 
    show2() => 20; 
    } 
} 
0

Вы на самом деле не сделал переопределить методы ....

`System.out.println (" Data1 = "+ b.data);

System.out.println («Data2 =» + b.data); `

для этих двух линий«данные»значение будет извлекалось из переменных данных класса В. Теперь, класс B расширяет класс A, что означает, что все члены класса A получат наследование в классе B.so переменная i (класса A) будет наследоваться, а внутри класса B мы будем иметь свою локальную переменную i ...... show1 () метод класса A также получит наследование в классе B. Итак, используя ссылочную переменную (b) класса B, мы можем получить доступ к методу show1(), а также к методу show2().

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