Reputation: 4940
what is the need of having a rule like this in java :
"a subclass cannot weaken the accessibility of a method defined in the superclass"
Upvotes: 4
Views: 1206
Reputation: 31813
class Person {
public String name() {
return "rambo";
}
}
// subclass reduces visibility to private
class AnonymousPerson {
private String name() {
return "anonymous";
}
}
It's legal to call the following method with either a Person
, or an AnonymousPerson
as the argument. But, if the method visibility was restricted, it wouldnt' be able to call the name()
method.
class Tester {
static void printPersonName(Person p) {
System.out.println(p.name());
}
}
//ok
Tester.printPersonName(new Person());
this call is legal, because a Person
is a AnonymousPerson
, but it would have to fail inside the method body. This violates "type safety".
Tester.printPersonName(new AnonymousPerson());
Upvotes: 1
Reputation: 83235
What it means
The subclass method cannot have a more restrictive visibity than the superclass method.
For example, if the superclass defined
protected void a() { } // visible to package and subclasses
the subclass can override it with one of
public void a() { } // visible to all
protected void a() { } // visible to package and subclasses
but not
void a() { } // visible to package
private void a() { } // visible to itself
Why it is
Suppose the definition was
class A {
public void a() { }
}
class B extends A {
private void a() { }
}
Now, consider the following code
A instance = new B();
instance.a(); // what does this call?
On the one hand, any B
has a publically accessible a
method. On the other hand, the a
method of a B
instance is only accessible to B
.
More generally, a subclass(interface) must fulfill the contract of its superclass(interface).
Visibility is only one example of this principle. Another example is that a non-abstract class must implement all methods of any interface it implements.
Upvotes: 2
Reputation: 279950
If you have a class with a public method
public class Foo {
public void method() {}
}
This method is accessible and you can therefore do
Foo foo = new Foo();
foo.method();
If you add a subclass
public class Bar extends Foo {
@Override
public /* private */ void method() {}
}
If it was private
, you should not be able to do
Foo bar = new Bar();
bar.method();
In this example, a Bar
is a Foo
, so it must be able to replace a Foo
wherever one is expected.
In order to satisfy the above statement, a sub class cannot make an inheritable member less accessible. It can however make it more accessible. (This basically only applies to methods.)
Upvotes: 2
Reputation: 41281
To fulfill the interface contract. Let's say I have an interface, IFlying
, as:
public interface IFlying {
public void fly();
}
And I have an implementation that weakens accessibility:
public class Bird implements IFlying {
private void fly(){
System.out.println("flap flap");
}
}
I now have some library function that accepts an IFlying, and calls fly
upon it. The implementation is private. What happens now? Of course, it means that the fly method cannot be accessed.
Hence, the accessibility may not be made more restrictive in an implementation.
Upvotes: 0