Domanda

Curious as to why for the following code

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();

     }


}

The output is

start Outerclass 20 InnerClass 10 Outerclass-2 20

But if int i is declared private the output is

start Outerclass 20 InnerClass 30 Outerclass-2 30

Could someone explain?

È stato utile?

Soluzione

When the field has no access modifier, it has default visibility.

From the scope of InnerClass#printme(), a sub class' method, it is accessible. So

i+=10;

is accessing the InnerClass instance's field, which was initialized to 0.

private fields are not visible to sub classes, so InnerClass can't access its own. But because your InnerClass is an inner class which is within the body of the OuterClass it can access the enclosing instance's field. So

i+=10;

is accessing the OuterClass instance's field.

Altri suggerimenti

A private field cannot be accessed in a sub-class but is can be accessed in an inner class.

So if you have

int i;

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

however

private int i;

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

Sure. If it's not private, then its inherited by InnerClass - that is, the i that's operated on is the one in the InnerClass object. If it is private, it can't be inherited, so the i that's operated on is the one in the containing object.

InnerClass is not strict inner class, which is commonly known from declarations in class body. In this case it is local class and is indeed a kind of inner class, but quite different rules are applied. This problem is all about inheritance and consequently - shadowing variables.

In your case, if you extend class with default (none) modifier you can access this field and effectively you can see superclass's field.

If field is declared as private, then subclass cannot see it, but it has its own as it extends your OutterClass so the new object starts with default value of 0.

Look here at the documentation's part about Shadowing and local classes

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top