2015-08-05 3 views
0
public class Print1 { 
    int x = 1; 
    public void print(A a) { System.out.println(x); } 
    public void print(B b) { System.out.println(x+1); } 
}  

public class Print2 extends Print1 { 
    int x = 3; 
    public void print(A a) { System.out.println(x); } 
    public void print(B b) { System.out.println(x+1); } 
    public void print(C c) { System.out.println(x+2); } 
} 

// a tester class with main method 
A a = new A(); B b = new B(); C c = new C(); 
Print1 p1 = new Print1(); 
Print2 p2 = new Print2(); 
p1 = p2; 

System.out.println(p1.x); // Call 1, p1 is from Type Print1 
p1.print(c); /* Call 2 
//p1 is from Type Print2, print(B b) will be called */` 

Класс B является подклассом класса A и C является подклассом В.в Java (методы доминирующих и "полей")

  1. почему в вызове 1 P1 от типа Print1 несмотря на то, он ссылается на объект типа Print2, а в вызове 2 он ведет себя как ссылка на Print2 -объект?

  2. Почему в Call 2 print(B b) называется от Print2, а не print(C c)?

Это самая запутанная вещь для меня до сих пор на Java. Спасибо за помощь.

+1

Возможный дубликат [http: // stackoverflow.ком/вопросы/30558552/метод-наиважнейшая-против-класса переменной-наиважнейшая-в-Java] (http://stackoverflow.com/questions/30558552/method-overriding-vs-class-variable-overriding-in-java) –

ответ

0

типа переменной используется для определения члена класса, доступ.

Поэтому p1.x относится к x Фиэлю d в Print1, а не в Print2. (это приведет к ошибке времени компиляции, если вы удалили x из Print1.) Поле x в Print2 - это другое поле, то есть Print2 объекты имеют 2 разных поля int.

Также метод print(B b) используется в выражении p1.print(c), поскольку Print1 не имеет способа print(C c). (Это будет ошибка времени компиляции, если C не будет распространяться на B или A.) Поскольку Print2 переопределяет реализацию Print1.print(B b), эта реализация используется.

+0

Спасибо, Фабиан, очень ясный ответ. – Miloud21

0

Первая печать работает, как ожидается, из-за переменная тень.

У вас есть переменная p1 (тип Print1), указывающая на объект на куче типа Print2. Так как Print2 наследуется от Print1, это разрешено. И вы можете получить доступ к переменной x из Print1, потому что для переменных нет полиморфизма, они не могут «переопределять» друг друга. Ваш тип переменной определил, что вы выбрали x.

Было бы менее сложно, если бы вы добавили другую переменную int y в категорию Print1. Вы могли бы получить к нему доступ как System.out.println(p1.y); без проблем.


Второй также работает как ожидалось в связи с полиморфизм (через наследование).

Поскольку print(c) метод выполняется на объекте, объект, очевидно, типа Print2 (не имеет значения, какой тип переменной (Print1 или Print2), вы будете использовать Print2 'метод s. Просто потому, что Print2-х метод был переопределен метод Print1 «ы.

+0

Спасибо, darijan, это было полезно. – Miloud21

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