157

Why are all methods in an interface definition implicitly public? Why does it not allow a protected method?

Swaranga Sarma
  • 13,055
  • 19
  • 60
  • 93
  • 38
    Very good question. For almost every other thing in Java I have found a real reason for the choices made, but for this one I haven't. It makes perfect sense to me to define a protected method in an interface which allows another class inside the same package to use this method on an implementing object without requiring to expose that method, which may not be meant to be called by anyone other than the package members, to the rest of the world. – Markus A. Oct 01 '12 at 18:44
  • 6
    @MarkusA. But interfaces work two-way, i.e. they can also be implemented by classes outside the current package (and then perhaps passed as arguments to methods inside this package). How would a class from outside the current package be able to implement "protected" methods of some public interface? – MartinStettner May 23 '13 at 10:47
  • 12
    @MartinStettner: It wouldn't. That would be the point. A package might have multiple unrelated classes which implement an interface, and want to guarantee to any code receiving a reference of that interface type that it will behave a certain way. Such a guarantee could be made much stronger if outside code could be prevented from claiming to implement the interface while behaving in a fashion contrary to its contract. – supercat May 23 '13 at 15:37
  • 4
    @MarkusA. you raised a good point, you should be able to achieve it with [Java 9's module system](https://en.wikipedia.org/wiki/Java_Module_System) – Nir Alfasi Apr 07 '16 at 17:35
  • 1
    if interface has `protected` method , all implementing class will be seen as a sub-type of the interface. and all these classes CAN access protected methods. doesnt it make `protected` keyword on method useless? as long as we dont have any ways to restrict **who implements this interface** protected keyword on method is useless. correct me if im wrong! – amarnath harish Jun 06 '18 at 10:31
  • Protected methods in an interface would make sense. For example, I am designing an interface for objects that implement an interpreter. You can set input, output, variable values, source code to execute and then you can execute. There are setters for all these parameters, but there are also versions of the methods that implement a builder pattern, and they have a `default` implementation. The setter methods are not to be used, but to be implemented so that the builder pattern can use them. In this case, the setter methods could be protected. – Peter Verhas Jul 30 '18 at 10:14
  • Not directly relevant to the question, but there is an interesting thread on requesting the same feature in Kotlin: [Interface method in Kotlin should support protected && internal visibility modifier](https://discuss.kotlinlang.org/t/interface-method-in-kotlin-should-support-protected-internal-visibility-modifier/1918) – skomisa Dec 04 '19 at 12:34
  • c# 8, allows you now to have protected member – Kiarash Jan 22 '20 at 23:29
  • 1
    @alfasin Your comment was prescient. That is precisely the approach later proposed as an alternative to having protected interfaces. See [JDK-8179193 Protected methods in interfaces: share across packages](https://bugs.openjdk.java.net/browse/JDK-8179193). – skomisa Jun 05 '20 at 05:35
  • @MartinStettner if the method is protected, it means all classes inside the same package and all subclasses can access it. I think it makes perfect sense to have protected methods on interfaces. Private ones were already introduced on Java 9. – Manoel Campos Mar 15 '23 at 17:06

15 Answers15

78

Because an interface is supposed to mean "what you can see from outside the class". It would not make sense to add non-public methods.

Raveline
  • 2,660
  • 1
  • 24
  • 28
  • 21
    But why not have functions that only members of the same package as the interface "can see from outside the class"? I've had several use-cases where I was wishing for this. – Markus A. Oct 01 '12 at 18:45
  • 6
    @MarkusA. I realize this is late, but then you can make a fully `abstract class`, which is all `interface`s are, and specify whatever access you want. Granted this loses the benefit of multiple implementations that `interface`s get in Java, but honestly establishing a contract that adheres to limitations of some other package would be untestable and confusing, as you would not practically be able to access your own implementation's method outside of that package. – pickypg Apr 18 '13 at 05:49
  • 12
    @pickypg But if the class that would implement the interface already extends another class, you cannot make it extend another class. I wouldn't find it confusing for an interface that is used only inside a package. – Flamma Jan 15 '14 at 10:22
  • 31
    @Raveline, -1, This begs the question "why is an interface supposed to mean what you can see from outside the class?" Java 8 already allows method body in interfaces, so why not allow protected abstract methods as well? – Pacerier Aug 23 '14 at 07:47
  • 1
    If you define a method as default-package-private in a interface, then the compiler implicitly assumes you meant public. You will notice when implementing the package-private method in the concrete class, also as package-private, that the compiler might say `attempting to assign weaker access privileges; was public`. – djangofan Jan 14 '17 at 18:50
  • 13
    I often read this explanation, but it's wrong IMHO. An Interface is sort of a "standard exchange protocol", no matter if talking about OOP, communication API or hardware. The USB port on my PC is clearly a public interface. But the pins on my mainboard, that is behind a key-locked case, that provide access to optional USB ports are clearly a "protected" interface. Then we have the BIOS chip - which is also a standardized interface, but it's never made public in any way, only a few companies know the exact details in private. So, of course, interfaces can have any visibility! Why not in OOP? – Foo Bar Jan 21 '18 at 14:14
  • 1
    Not true anymore with Java 8's default methods. – Mario Rossi Aug 08 '18 at 08:14
  • 1
    There's a difference between "what you can see from outside the class" and "what you can see from outside the _package_". I wish we could have more control over what is seen outside the package (aka the rest of the world). – Benny Bottema Jun 21 '19 at 17:52
  • 1
    @Raveline Can you support your claim that _an interface is supposed to mean "what you can see from outside the class"_ with any authoritative source? As far as I can tell it's just a definition that you made up which is not, and never was, true. But even if it was true, your answer still does not address the OP's question, because a protected interface method could still be seen _"from outside the class"_. – skomisa Dec 04 '19 at 06:59
74

Although the often quoted reason is that "interfaces define public APIs", I think that is an over-simplification. (And it "smells" of circular logic too.)

It would not be meaningless to have interfaces that have a mixture of access modifiers; e.g. partly public and partly restricted to other classes in the same package as the interface. In fact, in some cases this could be down-right useful, IMO.

Actually, I think that the part of reasoning behind making members of an interface implicitly public is that it makes the Java language simpler:

  • Implicitly public interface members are simpler for programmers to deal with. How many times have you seen code (classes) where the method access modifiers were chosen seemingly at random? A lot of "ordinary" programmers have difficulty understanding how best to manage Java abstraction boundaries1. Adding public/protected/package-private to interfaces makes it even harder for them.

  • Implicitly public interface members simplify the language specification ... and hence the task for Java compiler writers, and the folks who implement the Reflection APIs.

The line of thinking that the "interfaces define public APIs" is arguably a consequence (or characteristic) of the simplifying language design decision ... not the other way around. But in reality, the two lines of thought probably developed in parallel in the minds of the Java designers.

At any rate, the official response to the RFE in JDK-8179193 makes it clear that the Java design team decided2 that allowing protected on interfaces adds complexity for little real benefit. Kudos to @skomisa for finding the evidence.

The evidence in the RFE settles the issue. That is the official reason why that has not been added.


1 - Of course, top-gun programmers have no difficulty with these things, and may welcome a richer palette of access control features. But, what happens when their code is handed over to someone else to maintain?
2 - You may disagree with their decision or their stated reasoning but that is moot.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
31

I have to say that this question has been re-opened by the introduction of default methods in Java 8. The project that I am working on right now is, similar to the base nature of an interface, meant to abstract intention from implementation.

There are several cases in which I could drastically simplify my code with a "default protected" method. It turns out that that doesn't actually work, as interfaces still stick to Java 7 logic. A normal protected method doesn't especially make any sense, for the reasons mentioned above; but if a default public method requires a low-level resource that will not likely change and can be provided by a protected method, it seems to me that having "default protected" work would not only maintain cleaner code, it would protect future users from accidental abuses.

(This tragically does not change the fact that I still need to over-complicate my code with otherwise unnecessary abstracts; but I do intend to put a feature request in at Oracle.)

Michael Oberlin
  • 479
  • 4
  • 4
  • 5
    I agree 100%. Abstract classes were a sensible alternative prior to the introduction of default methods. However, the limitations that they place on multiple inheritance means that they are not perfect. Interfaces with default methods are normally better alternative in a >= JDK 1.8 world, but because they can't store state they rely on defining other abstract methods to expose the state, which means that the state is made public, which is not always what you want. – Fr Jeremy Krieg Feb 05 '20 at 05:32
15

Several answers here employ circular reasoning to explain why interface methods can't be protected: it's because they have to be public, so obviously they can't be protected!

That explains nothing, but fortunately someone raised an enhancement request for protected methods in interfaces as a JDK bug a couple of years ago, which sheds some light on the issue:

Protected methods in interfaces: share across packages

Since modifiers are a bit limited in Java, a way to share methods across packages is restricted to public methods. Sometimes it is dangerous to make a method public, but it needs to be because of the lack of proper modifiers. My solution overcomes this limitation.

The java language specification doesn't currently allow the protected modifier for interface methods. We can take advantage of this fact and use protected for interface methods for this new feature.

If an interface method is marked protected and the interface is implemented by a class in another package, the method would not need to be public, but could also be private or at least package protected. The method is visible, what ever the class declares it to be and additionally visible in the source package of the interface (and sub packages?).

This way we could share certain methods across well known packages.

And this is the response to that enhancement request, which was closed with status Won't fix:

This proposal attempts to solve a problem in a way that adds complexity and special cases for little actual gain. A typical way to solve this problem is to have a private class that implements a public interface. The implementation methods are public, but are within a private class, so they remain private.

An alternative available starting in Java 9 is to make classes and methods public, but within a module that has a qualified-export to specific "friend" modules instead of being exported to the general public.

So the authoritative takeaways from that bug report are:

  • The current situation is not going to change; interfaces are unlikely to ever support protected methods.
  • The justification for not supporting protected methods in interfaces is that it "adds complexity and special cases for little actual gain".
  • Since Java 9 there is an alternative approach for providing package level access to methods. Use the Java Platform Module System (JPMS) to "make classes and methods public, but within a module that has a qualified-export to specific "friend" modules instead of being exported to the general public".
skomisa
  • 16,436
  • 7
  • 61
  • 102
12

Because interfaces define public APIs. Anything that's protected is an internal detail which does not belong in an interface.

You can use abstract classes with protected abstract methods, but interfaces are restricted to public methods and public static final fields.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • 6
    You stated "because interfaces define public APIs". So what's the reason that interfaces should define only `public` APIs? There's a difference between "internal detail" with "implementation detail", `protected` in Java is definitely not an internal detail as it is now a public interface [published to everyone](http://stackoverflow.com/questions/215497/in-java-whats-the-difference-between-public-default-protected-and-private/215579#215579) who can subclass it, which is basically the whole world. – Pacerier Sep 10 '14 at 19:01
  • 4
    Not true anymore with Java 8's default methods. – Mario Rossi Aug 08 '18 at 08:13
  • 3
    @MarioRossi And also not true anymore with Java 9's private interface methods. – skomisa Jun 05 '20 at 05:25
8

I strongly feel that interfaces should allow protected methods; who said that interfaces have to be visible to everyone in the whole world? As to your point that it might confuse "ordinary" (read:incompetent) programmers: So much of OOP is about properly structuring objects, classes, packages etc., if a programmer has a hard time with doing all that properly, he has a much bigger problem. Java was built for that type of thing.

IntelliData
  • 441
  • 6
  • 29
7

Perhaps, because it is an interface, i.e. it is there to tell clients what they can do with instances, rather than to tell them what they can not do.

Ingo
  • 36,037
  • 5
  • 53
  • 100
  • 2
    I don't see why an interface couldn't also tell subclasses what they can do without exposing that implementation to the outside world. This was a design decision that was made at a time when abstract classes could be used as a perfect alternative. But with the advent of default methods in interfaces, abstract classes are now an imperfect alternative. – Fr Jeremy Krieg Feb 05 '20 at 05:23
4

Since an implementing class must implements ALL the methods declared in your interface, what would happen if your implementing class was in a different package ?

dm76
  • 4,130
  • 8
  • 35
  • 46
3

Declaring internal subinterfaces is a good practice, but you can not declare your internal methods as protected in an interface in Java, technically.

Of course, you can create another interface for internal use which extends the public interface:

package yourpackage;

public interface PublicInterface {

    public void doThing1();

    public void doThing2();

    public void doThing3();

}

package yourpackage;

interface InternalInterface extends PublicInterface {

    void doAnyInternalThing1();

    void doAnyInternalThing2();

}

You may use the InternalInterface interface inside the package, but you should accept any subtype of PublicInterface (in public methods):

package yourpackage;

public class SomeClass {

    public void someMethod(PublicInterface param) {
        if (param instanceof InternalInterface) {
            // run the optimized code
        } else {
            // run the general code
        }
    }

}

Outside the package users can use PublicInterface without problems.

Usually programmers create abstract classes in similar situations. However, in this case we lose the benefits of multiple inheritance.

Dávid Horváth
  • 4,050
  • 1
  • 20
  • 34
  • 2
    Outside the package users can use `YourPublicInterface.Internal`, too. Everything in an interface, including nested interfaces, is public regardless of the presence or absence of the `public` keyword. – Greg Roelofs Sep 04 '18 at 21:04
  • This solution works fine. The only thing I'm trying to avoid is the casting/instanceOf. Even "pattern matching for instanceof" in JDK 16 making things easier, you still need to handle it. Still looking for a cleaner alternative. If you have different classes/methods you pass a PublicInterface as a parameter, the casting becomes inconvenient and boilerplate. – Manoel Campos Mar 15 '23 at 17:41
2

Interface If you want to use something like you described go on with abstract classes or nested interfaces.

An exerpt from the Code Style about interface variables, but still apply to methods though:

Interface variables are implicitly public because interfaces are intended to provide an Application Programming Interface (API) that is fully accessible to Java programmers to reference and implement in their own applications. Since an interface may be used in Java packages that are different from their own, public visibility ensures that program code can access the variable.
grizzly
  • 1,146
  • 12
  • 26
2

Non-public members are generally used by public members. For example, AbstractList.removeRange(int, int) is used by AbstractList.clear(), and overriding it will improve the performance of clear.

If protected methods are allowed in interfaces, it means that most public default implementations will rely on these methods. If a subclass does not need default implementations and override all public methods, then all non-public methods will no longer be useful. And if they are abstract, we will still have to override them, which makes subclasses complicated.

1

The only scenario where it would make sense is when you want to restrict visibility to the same package. All the other uses of protected are not applicable. Specifically, protected methods are often used to provide access to some details of lower level implementations for descendants. But declaring that in an interface doesn't make sense, as there's no lower level implementation to expose.

And even the package scenario is not really what interfaces are about.

To achieve what you probably want, you need two interfaces, one for internal use and one that you expose in the public API. (With the internal one possibly, but not necessarily extending the public one.) Or, as others pointed out, an abstract superclass.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • An abstract superclass can prevent itself from being derived by types outside its package. Someone receiving a reference of such a superclass type, who trusts the author of the package, can be assured that the object will behave as claimed. If a package has multiple classes which want to expose some common functionality, but don't fit a proper hierarchy (e.g. one implement functions X and Y, one Y and Z, and one X and Z) it would be helpful if it could expose the functionality using interfaces while still promising that instances referred to by the interface types would be "genuine". – supercat May 23 '13 at 15:42
0

Protected methods are always accessible by sub-class only if subclass extends the base class.

In case of interface, subclass never extends the interface. It implements the interface.

Protected methods are accessible via extend and not with implement.

Aftaab Siddiki
  • 241
  • 3
  • 4
0

Interfaces are meant to expose methods to the outer world. Thus these methods are public by nature. However, if you want to introduce abstraction within the same family of classes it is possible by creating another level of abstraction between your interface and implementation class, i.e. an abstract class. An example is demonstrated below.

public interface MyInterface {
    public void publicMethod(); // needs to be public
}

public abstract class MyAbstractClass implements MyInterface {
    @Override
    public void publicMethod() {
        protectedMethod(); // you can call protected method here
        // do other stuff
    }
    protected abstract void protectedMethod(); // can be protected
}

public class MyClass extends MyAbstractClass {
    @Override
    protected void protectedMethod() {
        // implement protected method here, without exposing it as public
    }
}
Stefanos Kargas
  • 10,547
  • 22
  • 76
  • 101
  • 2
    But private methods that no one will see are allowed in the interfaces. – Alex78191 Sep 18 '19 at 13:54
  • java has default methods in interfaces, that is, an interface is a crutch to bypass the multiple inheritance of abstract classes. Let then multiple inheritance of abstract classes is allowed. Conflicts of default methods did not become a problem. – Alex78191 Sep 18 '19 at 14:02
  • You are right. As of Java 9 private methods are allowed in interfaces. These cannot be abstract and they are implemented and used within the interface, mainly by other default or static methods (if they are static themselves). – Stefanos Kargas Sep 19 '19 at 14:18
  • 2
    This answer simply ignores the question asked: why can't interfaces have protected methods? Protected methods would still _"expose methods to the outer world"_, and the claim that _"these methods are public by nature"_ is just false. They're public because the language was designed that way, but it could have permitted protected methods in interfaces. The OP is simply asking why. – skomisa Dec 04 '19 at 07:09
0

I know this is very late/old and I am sure that by now you have a lot more experience than me, so if this helps anyone, cheers, ...

I've found a way that keeps things comfortably cohesive, that prevents the usage of objects when dealing with protected's in-package.

In hindsight this seems ridiculously easy, but the fact of the matter is that the goal of whatever is you want to achieve with a piece of code, becomes 10 times more difficult if you spend any amount of time to try to accommodate it to standards and/or adjusts for code reusability.

The reality is that the order, will unfold as you go..

But I made a chart cause it has helped me in something that, depending on the problem can easily mind-bend me.

enter image description here

public interface CommonPublics {
    void publicInAll();
}
public static abstract class CommonProtecteds implements CommonPublics {
    protected abstract void protectedInAll();
}
public interface MyObjectPublics {
    void myObjectPublic();
}
public static class MyObject extends CommonProtecteds implements MyObjectPublics {

    @Override
    public void publicInAll() {

    }

    @Override
    protected void protectedInAll() {

    }

    @Override
    public void myObjectPublic() {

    }
}

Now when you need to deal with protecteds within the same package, instead of dealing with MyObject, you can deal with CommonProtecteds instead.

Now you could in theory bring whatever logic that handles protected's inside the abstract and that's up to you, but if for whatever reason you are dealing with concurrency, is better to keep everything as tight and as close to the synchronized body as possible. so whatever the protected is required to deal with that may be required inside different locked locations is better placed in the object that will handle it.

Delark
  • 1,141
  • 2
  • 9
  • 15