David
Posts: 150
Nickname: archangel
Registered: Jul, 2003
|
|
Re: Thumb rule for access specifiers in inheritance
|
Posted: Aug 20, 2003 1:51 AM
|
|
OK. First things:
(a) private->default->protected->public (b) private->protected->default->public
The 'default' visibility is definitely less visible than protected. If you declare something as 'default' visibility, that thing (method, variable, class etc.) can be accessed directly by anything within the same package as the thing (method, variable, class etc.)
The 'protected' visibility is the same as 'default' visibility, except that the thing (method, variable, class etc.) is accessible if the class is subclassed into a different package.
An example:
package foo;
public class A {
protected int i; // 'protected' visibility
float f; // 'default' visibility
}
package foo;
public class B extends A {
public B() {
this.i = 7; // accessing protected variable directly.
this.f = 7.0f; // accessing default variable directly.
}
}
package bar;
import foo.*;
public class C extends A {
public C() {
this.i = 7; // accessing protected variable directly.
this.f = 8.0f; // WRONG!!!! Can't do this!
}
}
As you can see, protected offers wider visibility.
By "unambigious call" I meant that it is always possible to decide which method to run. For example:
class A {
public void foo() {
System.out.println("Public foo()");
}
}
class B extends A {
protected void foo() {
System.out.println("Protected foo()");
}
}
class Test {
public static void main(String[] args) {
A myVar = new B();
myVar.foo(); // Which method to run?
}
}
Which method should be run? Class B has a foo() method defined, but it's only accessible from object instances of classes defined in its own package. You *could* say "well, if you can accessed the protected version, run that, otherwise run the public version". However, this would mean that which method gets executed is dependant upon which class invokes the method call!
However, the point I don't think I really emphasised (why I consider the main reason behind this visibility issue) is that of good OO design. Given the following code:
class A {
public void method1() {}
public void method2() {}
public void method3() {}
}
class B extends A {
public void method1() {}
public void method2() {}
private void method3() {}
}
class C extends B {
public void method1() {}
private void method2() {}
private void method3() {}
}
class D extends C {
public void method1() {}
public void method2() {} // is this overriding?
public void method3() {} // or is it a completely new method?
}
You know that if one class extends another then you obtain the interface (i.e. the set of available methods) of the superclass. However, as the above example shows, if you can restrict the visibility of methods in a subclass, the public interface isn't passed down through the hierarchy - leading to anarchy!
|
|