Затенение переменной в Java, несколько случаев статическое / нестатическое - PullRequest
1 голос
/ 15 февраля 2020

В последнее время я проходил курс обучения по Java, и мы имеем дело с выходными данными программы, ошибками компиляции и т.д. c. Я сам пробовал разные коды, и одна вещь из моих экспериментов действительно смутила меня: во-первых, основной метод выглядит следующим образом:

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

     System.out.println(a.a + " " + b.a + " " + ab.a);

}

Теперь я попробовал эти разные версии:

//1
public class A {
  public static int a = 1;
   public A() {
    a = 11;
   }
}
public class B extends A {
  public static int a = 2;
   public B(){ a = 22;}
}
//------------
//2
public class A {
  public int a = 1;
   public A() {
    a = 11;
   }
}
public class B extends A {
  public static int a = 2;
   public B(){ a = 22;}
}
//--------------
//3
public class A {
  public static int a = 1;
   public A() {
    a = 11;
   }
}
public class B extends A {
   public B(){ a = 22;}
}
//-----------
//4
public class A {
  public int a = 1;
   public A() {
    a = 11;
   }
}
public class B extends A {
   public B(){ a = 22;}
}

Выходы следующие:

  1. 11 22 11

  2. 11 22 11

3: 11 22 22 * ​​1024 *

22 22 22 * ​​1028 * Хотя я могу понять, что выводы 1 и 2, 3 и 4 действительно сбивают меня с толку. Для 3: a = 22 * ​​1035 * в B, изменяет значение a для объекта A ab, потому что int a не объявляется снова в B? И для 4: если int a в A не является stati c, а a является объектом типа A, почему aa имеет значение ba? Что происходит в 4, когда я установил int a как nottiti c? Заранее спасибо!

1 Ответ

1 голос
/ 15 февраля 2020

Важное примечание: ответ для случая 4: 11 22 22 * ​​1001 *

В случае 3: когда A ab = B () исполняемый конструктор B устанавливает переменную stati c a в A, чтобы он имел значение 22.

в случае 4: оба класса A и B имеют поле экземпляра (a) (фактически класс B наследует этот атрибут от класса A), а во время построения сначала выполняется конструктор класса A, а затем конструктор класса B, поэтому, когда у нас есть a a = B (), первый конструктор класса A устанавливает переменную a равной 11, а конструктор класса B устанавливает ее равной 22 stati c. Поле в дочернем классе не переопределяет * поля в родительском классе, они просто скрывают поля stati c в родительском классе, если вы обращаетесь к stati c результат не зависит от типа самого объекта, но зависит от типа ссылки, которую вы используете для доступа к этому объекту. поэтому, когда вы пишете A a = B (), если A и B оба имеют поле stati c, a, результат aa будет a в классе A, а не a в классе B, потому что тип ссылки, которую вы используете для доступа к объекту ct здесь A, а сам тип объекта B.

...