This discussion is archived
7 Replies Latest reply: Jun 10, 2013 10:40 PM by VineetMGupta RSS

Encapsulation issue:protected attributes should be visible to child classes

VineetMGupta Newbie
Currently Being Moderated
Hi guys, I found the following inheritance and encapsulation issue and I was wondering if anyone could explain it to me:

Suppose you have a parent class with a non-static protected attribute (I know that's a mouthful, thanks for following).

package package1;
public class Parent{
protected int a = 10; // this is the non-static protected attribute in question
public static void main(String args[]){
// whatever logic
}// end Parent class
}// end main()

Now suppose you have a child class in another package and you have imported in the parent class.

package package2;
import package1.Parent;
public class Child extends Parent{
public static void main(String[] args){
Parent p = new Parent();
Child c = new Child();

System.out.println(p.a); //should print out 10 BUT DOES NOT
System.out.println(c.a); //should print out 10
}// end main()
}// end Child class


My observation is that p.a produces an error even though, to the best of my knowledge, it should not. I believe the statement "System.out.println(p.a);" should print out a 10.

Am I misunderstanding something about inheritance and encapsulation? Could someone tell me if there is a problem with my understanding or a problem with the Java language?

Thanks for reading this far. I hope you are as interested in this issue as I am. : )
-Vineet Gupta
June 6, 2013

Edited by: 1010389 on Jun 6, 2013 11:44 PM

Edited by: 1010389 on Jun 6, 2013 11:57 PM
  • 1. Re: Encapsulation issue:protected attributes should be visible to child classes
    Kayaman Guru
    Currently Being Moderated
    >
    Eh, shouldn't be so hasty in my answers.

    What protected here means that the foo is accessible to the subclass, but the main method is static and doesn't see "inside" the superclass per se.

    If you create a non-static method in subclass, you can access the variable of the superclass as if it were a variable of the subclass.
    It's the static context that is causing the perceived error here (even though it's not an error). If the variable is static in the superclass, you can access it in the way you're trying to.

    Edited by: Kayaman on Jun 7, 2013 11:38 AM
  • 2. Re: Encapsulation issue:protected attributes should be visible to child classes
    gimbal2 Guru
    Currently Being Moderated
    A stupid example might be in order here:

    Test:
    public class Test {
    
        protected int a;
         
        public Test(){
        }
    }
    Test2 which extends Test and references the protected attribute of Test in two different ways:
    public class Test2 extends Test {
    
      private Test parent;
      
      public Test2(){
        parent = new Test();
        parent.a = 10;
        this.a = 20;
      }
      
      public void printIt(){
        System.out.println("A of parent: " + parent.a);
        System.out.println("A of self: " + a);
      }
    
      public static void main(String[] args){
      
        Test2 t2 = new Test2();
        t2.printIt();
      }
    }
    A side note just in case you didn't realize yet: not every class needs a main(), only the ones you actually want to execute.
  • 3. Re: Encapsulation issue:protected attributes should be visible to child classes
    rp0428 Guru
    Currently Being Moderated
    >
    Hi guys, I found the following inheritance and encapsulation issue and I was wondering if anyone could explain it to me:

    Suppose you have a parent class with a non-static protected attribute (I know that's a mouthful, thanks for following).

    package package1;
    public class Parent{
    protected int a = 10; // this is the non-static protected attribute in question
    public static void main(String args[]){
    // whatever logic
    }// end Parent class
    }// end main()

    Now suppose you have a child class in another package and you have imported in the parent class.

    package package2;
    import package1.Parent;
    public class Child extends Parent{
    public static void main(String[] args){
    Parent p = new Parent();
    Child c = new Child();

    System.out.println(p.a); //should print out 10 BUT DOES NOT
    System.out.println(c.a); //should print out 10
    }// end main()
    }// end Child class

    My observation is that p.a produces an error even though, to the best of my knowledge, it should not. I believe the statement "System.out.println(p.a);" should print out a 10.

    Am I misunderstanding something about inheritance and encapsulation? Could someone tell me if there is a problem with my understanding or a problem with the Java language?
    >
    Relax - everything is working exactly as designed. Your 'error' should be this
    >
    a has protected access in package1.Parent
    >
    That access is NOT allowed because your child class is in a DIFFERENT package. If you move your 'Child' class to package1 everything will be fine. Has nothing to do with 'the main method is static and doesn't see "inside" the superclass'.

    See section '6.6.2 Details on protected Access' in The Java Language Spec'the main method is static and doesn't see "inside" the superclass
    http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf
    >
    6.6.2 Details on protected Access

    A protected member or constructor of an object may be accessed from outside
    the package in which it is declared only by code that is responsible for the
    implementation of that object.
    >
    The example provided by gimbal2 only 'appears' to work because that example does not use packages. His example will give the same error if you put his Test class into your package1 and his Test2 class into your package2.
  • 4. Re: Encapsulation issue:protected attributes should be visible to child classes
    gimbal2 Guru
    Currently Being Moderated
    rp0428 wrote:
    The example provided by gimbal2 only 'appears' to work because that example does not use packages. His example will give the same error if you put his Test class into your package1 and his Test2 class into your package2.
    Oops :( Shame on me for being lazy.
  • 5. Re: Encapsulation issue:protected attributes should be visible to child classes
    VineetMGupta Newbie
    Currently Being Moderated
    Hey everyone, thanks for all your thoughts! You all know a lot so please hear me out because my argument is slightly different than what you all answered.

    I agree that changing the protected variable "a" to static would make it visible in the static main() of a child class, as Kayman said in a post.

    My assertion, however, is slightly different. I am saying that, per the rules of Java, I SHOULD be able to access the non-static protected variable in question through an object instance of the parent made in a child class (again, I know, quite a mouthful. I'm sorry).

    An important point to make, since rp0428 posted about it, is that the child class is in a different package than the parent class. That is done deliberately for the purpose of this thought experiment. Per the rules of Java, as I understand them, ANY child class - regardless of package - should be able to see protected variables.

    If the child class was in the same package as the parent, then the child would be able to see protected AND default encapsulated variables. But if the child is NOT in the same package, then it should still be able to see protected variables. Isn't that correct?

    Again, without a concrete answer I'm left to wonder if this is a hidden bug in the JVM. If so, my next question would be how do I report it?

    Thank you all for your time and for all your insightful thoughts on this issue. : )

    -Vineet Gupta
    June 7, 2013


    Edited by: 1010389 on Jun 7, 2013 3:30 PM

    Edited by: 1010389 on Jun 7, 2013 4:39 PM
  • 6. Re: Encapsulation issue:protected attributes should be visible to child classes
    rp0428 Guru
    Currently Being Moderated
    >
    An important point to make, since rp0428 posted about it, is that the child class is in a different package than the parent class. That is done deliberately for the purpose of this thought experiment. Per the rules of Java, as I understand them, ANY child class - regardless of package - should be able to see protected variables.
    >
    Then you didn't 'understand' the Java Language Spec section that I quoted.
    >
    If the child class was in the same package as the parent, then the child would be able to see protected AND default encapsulated variables. But if the child is NOT in the same package, then it should still be able to see protected variables. Isn't that correct?
    >
    No - that is NOT correct as the Spec section I quoted tells you.
    >
    Again, without a concrete answer I'm left to wonder if this is a hidden bug in the JVM. If so, my next question would be how do I report it?
    >
    You have a 'concrete' answer. It doesn't get any more 'concrete' than the Java Language Spec. It defines the rules and the one that I quoted applies to your use case.
  • 7. Re: Encapsulation issue:protected attributes should be visible to child classes
    VineetMGupta Newbie
    Currently Being Moderated

    rp0428,

     

    Yes, I concede to your point.  Thank you so much for taking the time to answer my question. 

     

    I missed that bit of nuance in the visibility rules.  Fortunately, you didn't.  Thanks again and happy coding!  : )

     

    Gratefully yours,

    Vineet Gupta

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points