Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java, Cannot reduce the visibility of the inherited method from object

Tags:

java

oop

api

Continuing from this question: Why can't you reduce the visibility of a method in a Java subclass?

I need to create class B that is almost identical to class A, except that B cannot do certain things that A can.

Being a lazy programmer as I am, I tried to inherit A, only to greet with error that B cannot reduce the visibility of A methods. Duh!..

Now A is an API from a vendor, my intention is to encapsulate this API so that it is easier to use.

I wonder what is the best practice to work around this?

like image 790
Rosdi Kasim Avatar asked Oct 28 '10 08:10

Rosdi Kasim


People also ask

Can we reduce the visibility of the inherited method in Java?

You cannot reduce the visibility of a inherited method. Here parent class has func() method which is public and overridden by the subclass TestClass which is private.

Can we change the visibility of method while overriding in Java?

Yes, an overridden method can have a different access modifier but it cannot lower the access scope. Methods declared public in a superclass also must be public in all subclasses. Methods declared protected in a superclass must either be protected or public in subclasses; they cannot be private.

Can inherited methods be overridden?

To override an inherited method, the method in the child class must have the same name, parameter list, and return type (or a subclass of the return type) as the parent method. Any method that is called must be defined within its own class or its superclass.


3 Answers

Two options:

If you need B to keep the same interface as A (so that client code can use any of the two without changes), you can override "forbidden" methods in B and have them throw an UnsupportedOperationException. For example:

public class A
{
    public int allowedMethod() { ... }
    public int forbiddenMethod() { ... }
}

public class B extends A
{
    public int forbiddenMethod()
    {
        throw new UnsupportedOperationException("Sorry, not allowed.");
    }
}

Or, if you really want the API of B to be a subset of the API of A, then just have B contain an instance of A, and delegate method calls appropriately.

    public class A
    {
        public int allowedMethod() { ... }
        public int forbiddenMethod() { ... }
    }

    public class B
    {
        private A a;

        public int allowedMethod()
        {
            return a.allowedMethod();
        }
    }
like image 129
Grodriguez Avatar answered Nov 17 '22 16:11

Grodriguez


Use Composition rather than Inheritance.

i.e. class B holds a reference to a class A and internally calls methods on it.

like image 9
William Avatar answered Nov 17 '22 18:11

William


A facade is used when one wants an easier or simpler interface to work with.

You would have to create your own wrapper class (Facade Pattern) around your foreign interface.

interface Foreign
{
    void dontWantThis();
    void keepThis();
}

interface/class MyForeign
{
    void keepThis();
}

The implementation would then have a instance of Foreign that it can refer calls to.

like image 4
willcodejavaforfood Avatar answered Nov 17 '22 18:11

willcodejavaforfood