I have an abstract base class with certain fields/abstract methods in it.
How do I make these visible to its children, even if the children don't live in the same package? (And I think public
is a bit too open, where protected
would not work!)
(To the comments below, protected
DOES NOT work because protected
fields are ONLY VISIBLE WITHIN the same package)
To prove the point, the following piece of code doesn't work. Please tell me why not.
package a;
public class Base
{
protected void foo() {}
}
// in a separate file/package
package b;
public class Child extends Base
{
private Base wrappedBase = new Base();
@Override
protected void foo()
{
wrappedBase.foo(); // <<<<< This throws "The method foo from type Base is not visible"
}
}
Normaly, you would just use protected
, which does work within subclasses within the restrictions in the JLS:
In foo/Parent.java
:
package foo;
public class Parent {
protected int x;
}
In bar/Child.java
:
package bar;
import foo.Parent;
public class Child extends Parent {
public Child() {
// Look ma, access to a protected variable declared
// by my superclass in a different package!
x = 10;
}
}
Now the example you've given is slightly different, because you're trying to access the protected variable via a compile-time type of Base
... and that doesn't work. You can only access a protected member via an expression with the same compile-time type as the code doing the accessing (or a subtype). As per section 6.2.2.1 of the JLS:
Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.
In addition, if Id denotes an instance field or instance method, then:
If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
There is no way of providing access to the protected member of all objects of the superclass to all subclasses. This is deliberate - it prevents code from creating a subclass simply in order to get access to more members of other types.
See more on this question at Stackoverflow