Number945
Number945

Reputation: 4940

Inheritance: weaker accessibility of a method in subclass

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

Answers (4)

goat
goat

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

Paul Draper
Paul Draper

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

Sotirios Delimanolis
Sotirios Delimanolis

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

nanofarad
nanofarad

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

Related Questions