Закрытая переменная внутреннего класса: объяснение значения?

1

Любопытно, почему для следующего кода

public class OuterClass{
  int i;
  public void printme(){
     System.out.println("Outerclass");
     i+=20;
     System.out.println(i);
       class InnerClass extends OuterClass {
          public void printme(){
              System.out.println("InnerClass");
              i+=10;
              System.out.println(i);
           }
        }

        InnerClass second = new InnerClass();
        second.printme();    
        System.out.println("Outerclass-2");
        System.out.println(i); 

        return;
     }

     public static void main(String []args){
        System.out.println("start");
        OuterClass first = new OuterClass();
        first.printme();

     }


}

Выход

start Outerclass 20 InnerClass 10 Outerclass-2 20

Но если int я объявлен private, выход

start Outerclass 20 InnerClass 30 Outerclass-2 30

Может ли кто-нибудь объяснить?

Теги:
oop
private
inner-classes

4 ответа

3
Лучший ответ

Когда поле не имеет модификатора доступа, оно имеет видимость по умолчанию.

Из области InnerClass#printme(), метод подкласса, он доступен. Так

i+=10;

обращается к InnerClass экземпляра InnerClass, который был инициализирован InnerClass 0.

private поля не видны для подклассов, поэтому InnerClass не может получить доступ к своим собственным. Но поскольку ваш InnerClass является внутренним классом, который находится внутри тела OuterClass он может получить доступ к закрывающему полю экземпляра. Так

i+=10;

обращается к OuterClass экземпляра OuterClass.

  • 1
    если вы дадите мне свой адрес, я вышлю вам более медленную клавиатуру. Вы всегда, кажется, били меня такими ответами.
  • 1
    @DavidWallace Я живу через дорогу от серверов Stackoverflow.
3

private поле не может быть доступно в sub-class но к нему можно получить доступ во внутреннем классе.

Поэтому, если у вас есть

int i;

// in InnerClass extends Outerclass
i += 10; // access the parent of this InnerClass

Однако

private int i;

// in InnerClass extends Outerclass
i += 10; // access the OuterClass as the parent is not accessible.
2

Конечно. Если он не является приватным, то его унаследовал InnerClass то есть i который работал on, является тем, что находится InnerClass объекта InnerClass. Если он является конфиденциальным, он не может быть унаследован, поэтому i который работал, является тем, который находится в содержащем объекте.

1

InnerClass не является строгим внутренним классом, который обычно известен из объявлений в классе. В этом случае это локальный класс и действительно является своего рода внутренним классом, но применяются совершенно разные правила. Эта проблема связана с наследованием и, следовательно, с переменными затенения.

В вашем случае, если вы расширяете класс с помощью модификатора по default (none), вы можете получить доступ к этому полю и эффективно увидеть поле суперкласса.

Если поле объявлено как private, то подкласс не может его видеть, но он имеет свой собственный, поскольку он расширяет ваш OutterClass поэтому новый объект начинает со значения по умолчанию 0.

Посмотрите здесь, в части документации о Shadowing and local classes

Ещё вопросы

Сообщество Overcoder
Наверх
Меню