Simulate private interfaces in java 8

carlos :

I'm having an issue regarding the simulation of public interfaces in java 8. I have this interface with this methods right now:

public interface A<T> {

    void method1(T t) throws someException;
    void method2(T t) throws someException;
    default method3() {
        return Collections.emptyMap();
    }
}

The interface A is implemented by class B, which is an abstract class:

public abstract class B<T> implements A<T> {
    @Override
    public void method1(T type) throws someException {
        // (.... some code snipets ....)
    }
}

The method1 contains all the logic and should be the one that the developer can see/use.

Now, bellow is represented the concrete representation of class B:

public final class ConcreteB extends B<someObject> {

    private static ConcreteB concreteBInstance = null;
    private ConcreteB() {
    }

    public static ConcreteB getInstance() {
        if (concreteBInstance == null) {
            concreteBInstance = new ConcreteB();
        }
        return concreteBInstance;
    }

    @Override
    public void method2(someObject someObject) throws someException {
        //  (... code ...)
     }
}

So, to summarize, the concrete implementation of B implements the method2 (and the method3, if the user wants to). The class B implements the method1, which contains all the logic.

My problem here is that when I do ConcreteB.getInstance(), the methods that are available for the developer to use are the method1, method2, and method3, and I want to make only the method1 visible to the developer. But because java 8 don't enable me to make private methods on interfaces, I don't know how to do it.

Any tips to how to solve this problem?

Thanks!

ernest_k :

You should not put those "private" methods in the interface. An interface would force the public API of B and all its subclasses to expose all three methods to the world. That's because interfaces are designed to define a public API.

What you can do in this case is move all methods from the interface to B, except method1:

public interface A <T> {
    void method1(T t) throws someException;
}

public abstract class B<T> implements A<T> {

    protected abstract void method2(T t) throws someException;
    protected method3() {
        return Collections.emptyMap();
    }

    @Override
    public void method1(T type) throws someException {
        (.... some code snipets ....)
    }
}

This way, you include in the public API only the methods you mean to include in it, and keep the rest only available to B and its subclasses. If the other two methods should not be accessible to subclasses of B, then you can make them private in B.

Further, if you want to prevent sub-classes of B from overriding method1, you can declare it as final.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=21189&siteId=1