2015-09-14 3 views
2
class Foo { 
    int number; 
    public Foo(int x) { 
     number = x; 
     multiply(); 
    } 
    public void multiply() { 
     number = 2 * number;  
    } 
    public int getNumber() { 
     return number; 
    } 
} 
class Bar extends Foo { 
    int number; 
    public Bar(int x,int y) { 
     super(x); 
     number = y; 
     multiply(); 
    } 
    public void multiply() { 
     number = number * 3; 
    } 
} 
class Test { 
    public static void main(String args[]) { 
     Foo foo = new Foo(42); 
     Foo bar = new Bar(42,24); 
     System.out.println(foo.getNumber() + "\n" + bar.getNumber()); 
    } 
} 

Результат этого кода - 84 и 42, но как бы я его не проследил, я получаю 84 и 72. Может кто-нибудь объяснить это подробно.Наследование в классах Java

+0

Можете ли вы показать, как вы отслеживаете его, чтобы получить '72'? – Pshemo

+2

24 * 3 действительно 72. Я не вижу здесь проблемы? – Stultuske

+0

В заявлении Foo bar = new Bar (42,24); называется конструктором Bar, который вызывает конструктор Foo, который вызывает функцию умножения, которая удваивает Foo.number. Затем Bar.number должен быть сделан 72, потому что в его конструкторе вызывается умножение, которое утроивает значение. Однако ответ 42. Не 72. –

ответ

5

Вот след:

Вызов new Bar(42,4):

42 передается super конструктор. Таким образом, она выполняет тело:

public Foo(int x) { 
    number = x; 
    multiply(); 
} 

number он использует в своей собственной number (Foo.number который скрыт), но multiply() он называет это переопределены один. Таким образом, он называет:

public void multiply() { 
    number = number * 3; 
} 

Но это относится к Bar.number, что на данном этапе все еще 0, поскольку он не был инициализирован. Таким образом, он остается 0. number в Foo не влияет, потому что это не number, который появляется в этой версии multiply.

Так что в данный момент у нас Foo.number на 42, и Bar.number на 0.

Далее мы продолжаем

number = y; 
    multiply(); 

Который ставит 24 в Bar.number, затем умножает его на 3.

Но getNumber() не переопределяется.Это означает, что когда вы вызываете bar.getNumber(), вы фактически получите number от Foo внутри него. Что такое 42.

1

Во втором случае в Foo bar = new Bar(42,24); для super(x),

public Foo(int x) { 
    number = x;//Now number in Foo is 42 
    multiply();// of Bar will be called not of Foo 
    //but currently number is 0 in Bar 
} 

Косвенно Foo#multiply(); не имеет никакого эффекта в вашем втором случае для number в Foo. Таким образом, multiply(); из Bar вызывается в конструкторе Foo, а ваш x, который сейчас находится number, находится в Foo, не имеет значения 42. i.e.Bar(100,24) предоставит вам номер 100 в вашем случае.

Вы не переопределяют getNumber в Bar вы будете иметь number от Foo, который 42.

Стоит отметить, что number в Bar теперь 72 из number = y и multiply метод Bar, который вы не использовали.

Ваш конструктор из Foo является похож на,

public Foo(int x) { 
    number = x; 
    this.multiply();// In second case 'this' refers to Bar and not Foo 
    //So that control goes to multiply method of Bar and not Foo 
} 
+0

Даже если '24 * 2' не' 42'. Этот парень абсолютно прав. Это становится 42, из-за супер (x) – kevintjuh93

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