конструктор и скрытие файла в Java

Я делаю это школьное упражнение и не могу понять, почему в следующих двух случаях будут разные результаты. Может ли кто-нибудь объяснить, почему в первом случае int x числа A равно 100? Разве int x в C не затеняет int x в A? Я также прокомментировал свой вопрос в коде. Большое спасибо!

class A {  // Case 1 
  public int x = 1;
  public String k() { return "A" + this.x; }
 }
class B extends A {
   public int x = 10;
}
class C extends B {
  public int x = 100;
  public String k() { return "C" + this.x; }
}
class TestABC {
  public static void main(String[] args) {
    A a1 = new C();
    C c1 = new C();
 } 
}
System.out.println(a1.x +"," + c1.x);// It prints out 1, 100.
   //However I thought it'd print out 100, 100, as the int x in C shadows int x in A. 

Другой случай

class A1 { //case 2
  int x=10;
  public void method() {
  System.out.print("A:" + this.x + " ");
  }
}
class B1 extends A1 {
  int x=20;
public void method() {
  System.out.print("B:" + this.x + " ");
}
public static void main(String args[]) {
   A1 s = new B1();
   s.method();// It prints out B: 20. 
   //What's the difference between this one and a1.x in the previous example? 
   //Why it prints out the subclass but in the previous code a1.x prints out the parent class?
   }
} 

person user3735871    schedule 12.09.2014    source источник
comment
Здесь обсуждается этот вопрос: stackoverflow.com/questions/17303662/ и здесь: stackoverflow.com/questions/10722110/overriding-variables-java   -  person galusben    schedule 12.09.2014


Ответы (2)


Первый случай выводит 1, 100, потому что он получает значение VARIABLE. Что-то вроде:

Get the value of x in A and get the value of x in C

Переопределение происходит только для METHOD, а не для VARIABLES. Вот почему во втором случае он вызывает метод внутри B1 вместо A1

Это называется полиморфизмом во время выполнения.


РЕДАКТИРОВАТЬ 2:

Позвольте мне объяснить это дальше:

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

Но с переменными все наоборот: вместо того, чтобы смотреть на тип объекта, JVM смотрит на тип ссылочной переменной и получает эта переменная

Учитывая следующий пример:

class Animal {

    String whatAmI = "An Animal";

    public void sayHi() {
        System.out.println("Hi from Animal");
    }
}

class Dog extends Animal {

    String whatAmI = "A Dog";

    public void sayHi() {
        System.out.println("Hi from Dog");
    }
}

Пример запуска:

//Reference variable type               //Object type
Animal              anAnimal            = new Animal();
Dog                 aDog                = new Dog();
Animal              anotherDog          = new Dog();

anAnimal.sayHi();       //Hi from Animal
aDog.sayHi();           //Hi from Dog
anotherDog.sayHi();     //Hi from Dog

Мы получаем эти выходные данные, потому что JVM вызвала метод sayHi() для типа объекта, а не для типа ссылочной переменной.

Но дело в том, что с переменными это не работает. Если мы попробуем что-то вроде:

System.out.println(anAnimal.whatAmI);       //An Animal
System.out.println(aDog.whatAmI);           //A Dog
System.out.println(anotherDog.whatAmI);     //An Animal

У нас есть эти выходные данные, потому что JVM получает переменную whatAmI из типа переменной Reference.

Чтобы запомнить это, нужно сосредоточиться на знаке равенства (=).

  • При вызове метода вызывайте метод справа от знака равенства (=).
  • При получении переменной получайте переменную слева от знака равенства (=).
person lxcky    schedule 12.09.2014
comment
Итак, в первом случае, когда a1 инициируется с использованием A a1= new C();, он содержит int x= 1 , но не int x= 100 как объект класса C? Спасибо! - person user3735871; 12.09.2014
comment
Спасибо за ответы! Еще один вопрос: значит, во втором случае s по-прежнему содержит int x= 10? Если это так, когда метод() System.out.print(B: + this.x +); называется, к чему это относится? - person user3735871; 12.09.2014
comment
Во втором случае x относится к 20, потому что в вашем методе System.out.print() вы используете this и помните, что this относится к классу выполняемому в данный момент. В данном случае это C, поэтому мы получаем значение C x. - person lxcky; 12.09.2014
comment
Конечно, спасибо! Вы имеете в виду, что во втором случае в методе System.out.print() ссылается на класс B1, и хотя нет объекта, содержащего int x= 20, но B1 по-прежнему является исполняемым классом, поэтому переменная int x= 20 используется? - person user3735871; 12.09.2014
comment
Давайте продолжим обсуждение в чате. - person lxcky; 12.09.2014

Да .. Это полиморфизм времени выполнения или переопределение.

Случай 1: A a = new C(); Случай 2: C c = новый C();

Правила полиморфизма:

                                          Variable            Method          Static Method
Reference of Superclass(Case 1)             Super               Sub               Super
Reference of Subclass(Case 2)                Sub                Sub                Sub

Это правила полиморфизма. Поэтому, если вы создаете какие-либо переменные-члены этих типов, вы всегда будете видеть результаты в этом формате.

Отсюда и результат, который вы видите.

person richa_v    schedule 12.09.2014