The Foo class can only access protected instances of an instance of type Bar if and only if Bar can be assigned to Foo . Ie if we can write:
Foo foo = new Bar();
For example, let's say that we have:
package a; public class Base { protected int protectedField; }
Then we can have this:
package b; import a.Base; public class Parent extends Base { void foo() { int i = this.protectedField; } void foo(Parent p) { int i = p.protectedField; } void foo(Child c) { int i = c.protectedField; } } class Child extends Parent { }
This will be compiled because all protectedField are accessible through Parent instances. Note that since the Parent reference can be an instance of Child (i.e., we can write Parent p = new Child(); ), we can access c.protectedField .
The following commands will not compile:
package b; import a.Base; public class Parent extends Base { void foo(Stepchild sc) { int i = sc.protectedField;
because the Stepchild instance Stepchild not an instance of Parent .
Somewhat vaguely, this also does not compile:
package b; import a.Base; public class Parent extends Base {} class Child extends Parent { void foo(Parent p) { p.protectedField;
this is because the Parent object is not a superclass or superinterface of the Child , therefore the Child cannot access its protected members.
If you are having trouble remembering, just think about whether you can write the type to the class type reference. For example, we can write:
Parent p = new Child();
but can't write
Child c = new Parent();
therefore, Child will not have access to the Parent protected members, and Parent will not have access to the Stepchild protected members.
Endpoint pair:
Remember that access to protected provides visibility between packages. In my experience, people forget about it.
Finally, protected static elements are always visible among the inheritance hierarchy.