Default
Both protected and default access levels are tied to packages. A class with default access has
no modifier preceding it in the declaration. Default access is simple in that only the code
within the same package
can access code with default access. In other words, a class with
default access can be seen only by classes within the same package. For
instance, if class A and class B are in different package, and class A
has default access, class B won't be able to create an instance of class
A or declare a variable or return type of class A. In fact, class B has
to pretend that class A doesn't even exist. We simply can't type it
into our code at all. If we do, the compiler will complain.
Let's take a look at the following file:
package packageA;
class classA {}
And another file:
package packageB;
import packageA.classA;
class classB extends classA {}
Then, we get the error from classB file:
The type packageA.classA is not visible.
classA can not be resolved to a type.
Let's think about the implications.
A default class with public methods means the public methods aren't
really public at all. We can't access a method if we can't see the
class.
Why would anyone want to restrict access to code within the same package?
In most of the cases, packages are designed as a group of classes
that work together as a related set. So it might make sense that classes
within the same package need to access one another's code, while as a
package, only a small number of classes and methods are exposed to the
outside the package.
Protected
Protected access is almost
identical to
default access. But with one critical exception. Protected access allows subclasses to
inherit the protected members even if those subclasses are
outside the package of the superclass they extend. In other words, a
default member may be accessed only if the class accessing the member belongs to the same package, whereas a
protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package.
Let's take a look at the following two classes:
package packageA;
public class AClass {
// default access
void test() {
System.out.println("classA");
}
}
Another file:
package packageB;
import packageA.AClass;
class BClass {
public static void main(String[] args) {
AClass ac = new AClass();
ac.test();
}
}
The
test() method in the first file has
default access. And the class
AClass is in a different package from the
BClass which is trying to access the method in
AClass.
It failed.
BClass is not in the same package as
AClass. So
BClass can't see
AClass.
Default and
protected behavior differ only when we talk about
subclasses. If the
protected keyword is used to define a member, any subclass of the class declaring the member can access it
through inheritance.
It doesn't matter if the superclass and subclass are in different
packages, the protected superclass member is still visible to the
subclass. This is in contrast to the default behavior, which doesn't
allow a subclass to access a superclass member unless the subclass is in
the same package as the superclass.
So, when you think of
default access, think
package restriction. But when you think
protected, think
package + kids.
One More Look - Protected
Let's take a look at a
protected instance variable of a superclass.
package packageA;
public class Parent {
protected int x = 10;
}
Another source:
package packageB;
import packageA.Parent;
class Child extends Parent {
public void test() {
System.out.println(" x = " + x);
}
}
The
Child class is accessing the
protected
variable through inheritance. Notice, though, any time we talk about a
subclass having access to a superclass member, we could be talking about
the subclass
inheriting the member,
not simply accessing the member through a reference to an instance of the subclass.
Watch what happens if the subclass Child tries to access a protected variable using a Parent class
reference.
First source is the same as previous example:
package packageA;
public class Parent {
protected int x = 10;
}
The differences are in this second file:
package packageB;
import packageA.Parent;
class Child extends Parent {
public void test() {
System.out.println(" x = " + x);
Parent p = new Parent();
System.out.println(" x in parent = " + p.x);
}
}
The compiler complains:
C:\ProtectedTest\src>javac -d . packageB/Child.java
packageB\Child.java:8: x has protected access in packageA.Parent
System.out.println(" x in parent = " + p.x);
^
1 error
The complain shows that subclasses outside the package can't use a superclass reference to access a protected member.
For a subclass outside the package, the protected member can be accessed only through inheritance.
Comments
Post a Comment