Why are all methods in an interface definition implicitly public? Why does it not allow a protected method?
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.
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.
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.)
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".
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.
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.
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.
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 ?
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.
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.
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.
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.
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.
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
}
}
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.
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.
Related
I am just now learning about Abstract classes in Java and I was wondering.
Would having package private fields be considered bad practices?
For example:
abstract class Parent {
String testField;
public void method() {
System.out.println(testField);
}
}
Then on the children class I would do
public final class Children extends Parent {
#Override
public void method() {
logger.log(testField);
}
}
In this example would it be bad practice?
Or should I make them private and instead use getters and setters for them like normally?
It depends on what you want to do. However, in many cases encapsulation or information hiding can be a useful principle. In your case, this would mean making the member variable protected or private and exposing it only through getters/setters or not at all. This yield some advantages:
You can change the implementation of your class (e.g. changing the type of testField) without breaking the code of other programmers
The code is more clear to other programmers as they only need to consider the public methods
It makes the code easier to test
It discourages feature envy and tight coupling
There's lots of advice. Prefer composition to inheritance. Prefer interfaces to base classes. Keep type hierarchies flat. Class should tend be either leaf (could be marked final) or abstract.
The most important practice here is avoiding protected. It's a mistake in the language. Also avoid default/package private access on anything but top level types.
In general (meaning exceptions are allowed under well defined circumstances), a field of a class should be private, and any access to it will require the use of a getter or a setter (or, more general, an 'accessor' or a 'mutator').
One (well known) exception is for static final fields of an immutable or primitive type – sometimes referred to as a constant.
When you can make sure (really sure) that your code is the only one that will access that field (for now and all overseeable future), you may consider to make it public (rarely), package private or protected. You will find this pattern quite often in classes from the java and javax packages; it works there because you cannot place your new classes to one of these packages, and therefore the code in your class cannot access the package private and protected fields – and because the (abstract) base classes in these packages that have protected fields are itself not public, inheritance would not help.
It will not work in most other cases (although things are changing since Jigsaw …), so you are limited to private internal classes in these cases.
Of course, when you write only disposable code, considerations like these are obsolete. Otherwise, you should always completely encapsulate all data, so that you/your code has complete control over any access/modification of it.
We can make methods protected in base abstract classes so that only sub classes override it.
protected void method() {
System.out.println(testField);
}
Okay I know this question has been asked a few times, but I need an advice on my specific case. There are Encodable's and Decodable's, and a Message is both an Encodable and a Decodable:
interface Encodable { void encode(); }
interface Decodable { void decode(); }
class Message implements Encodable, Decodable { ... }
void processEncodable(Encodable encodable) {
...
encodable.encode();
...
}
There are other Encodable's (and Decodable's) besides Message and they need to be processed in processEncodable. So far so good, but the problem is that I want to hide encode() and decode() from outside the package, and Java interface doesn't allow protected/private methods. One might suggest abstract classes, but as you can see Message should inherit both Encodable and Decodable, so that's not the case. Any suggestions?
These days I'm very much into Scala, and Scala traits allow protected/private methods and that's more intuitive IMHO. I've gone through a few answers mentioning Java interface's design philosophy, but I don't really understand why it shouldn't permit protected methods if interface was introduced as an alternative to multiple inheritance, while abstract classes do..
Being an alternative doesn't imply that it is a full substitute. Interfaces are Service Contracts and so they expose the functionalities that a certain class provides to its clients, being a client anyone with access to the interface.
If you want to hide encode and decode from outside the package (that means that your logic should also stay in the package with the Message class) don't expose them through the interface and, instead, allow them to be protected (or package private) methods of your Message class (or a superclass, if various classes will be encodable/decodable).
This is not an isolated rule. There are mechanisms to achieve what you want without breaking the concept of an Interface. Just think about this: What good does that method to the interface if you can access it only inside a package? What's the point of having such methods in an interface if they can be class methods that are, also, available to the members of the package with the proper modifiers?
I have a class with 5 methods. 3 of these methods just have to be opened by other classes in the same package and 2 have to be opened by other classes in an other package.
as example:
void setTimeArray(int[] zeitArray) {
this.timeArray = timeArray ;
}
public int[] getTimeArray() {
return timeArray ;
}
now I was wondering what I should make:
should I make the 3 methods protected and the 2 other public?
or
should I make an interface for the 2 methods?
so what would be cleaner and better for the performance of my application and why?
You seem confused about the use of public, protected, etc. The public methods in your class comprise the public interface of your class. When you design your class, you decide what functionality you want to expose to consumers of your class.
You should only make methods protected IMO for polymorphism. If you are making a method protected so that another class in the package can get at internals, etc., then it is probably a bad class design. You should not make a method protected just because no other classes are using it right now. If you need to use it from another class in the future, you'd have to change the class.
You shouldn't need to create an interface if there aren't multiple concrete classes implementing that interface.
The public interface of a class should flow pretty naturally if you get the OOP paradigm. The decisions should involve more about how to expose function than what to expose.
If there is a single "subject" that is common to the 2 methods but not to the other 3, consider splitting up the class into 2 different classes. If you do so, consider moving the class with the 2 methods to the package in which it will be used (if it makes sense in terms of the "subject" of that package).
In any case, use the lowest visibility that allows you to do what you wish to do.
Also, prefer default visibility to protected (the difference is that protected is like default, but also allows for subclasses in different packages to access those methods).
As the 3 methods of your class are access by the classes of the same package then no need to have a protected access modifier rather you can use default. protected should be used when you want your subclass to access the methods.
and about the public methods you can go for interface if you think you have a similar class which has these two methods implemented in it. so that through interface you can relate them.
You should write the interface as soon as you think, that you might use or need it ;)
In addition to the interface: keeping the non-interface methods protected is a valid solution for your problem.
Don't care about performance. Programming against interfaces or using access modifiers like public, protected or private has no performance impact.
Sometimes when I extend one of my own classes, I want to (for the purpose of the subclass) "inject" one or two lines of code in the middle a method in the super class.
In these cases I sometimes add a call to an empty protected method for the subclass to override.
public void superClassMethod() {
// some fairly long snippet of code
doSubclassSpecificStuff();
// some other fairly long snippet of code
}
// dummy method used for overriding purposes only!
protected void doSubclassSpecificStuff() {
}
When doing this several times in the same class I must say it looks quit awkward / ugly so my questions:
Is this way of "opening up" for subclasses to "inject" code in the middle of methods considered good practice or not?
Is the pattern (anti-pattern?) called something?
Has it been used in any well known API / library? (Note that I'm talking about non-abstract classes.)
Are there any better alternatives?
The only alternative I can come up with is to use something like the command pattern and have a setMiddleOfMethodHandler(SomeRunnableHandler), and call handler.doSubclassSpecificStuff() instead of the dummy-method. It has a few drawbacks as I see it though, such as for instance not being able to touch protected data.
You've just discovered the Template method design pattern. Note though that normally the methods that comprise the individual steps are abstract (rather than empty and protected) so that subclasses must override them.
There is the Template method pattern. The idea there is that much of the work is common, except for a few bits, which are handled by a subclass implemented method.
Yes, this is a legitimate way to do things; I've used it myself.
The only problem I can see is not the specific technique, but the fact that you are using subclasses of concrete (read: non-abstract) classes at all. Subclassing concrete classes has many subtle problems, so I would recommend to avoid it altogether. See e.g. http://en.wikipedia.org/wiki/Liskov_substitution_principle for an explanation of what you must do to properly subclass a class, and the problems involved. Also, in "Effective Java" Block recommends using composition (Item 16).
Another approach (that avoids subclassing) would be to use Dependency Injection. Your method would accept a parameter of a type that implements the interface ISpecificStuff, which specifies a method doSubclassSpecificStuff():
public void superClassMethod(ISpecificStuff specificStuff) {
....
specificStuff.doSubclassSpecificStuff();
....
}
That way, any caller can decide what the method should do. This avoids the need for subclassing. Of course, you could inject via a constructor, if you need it in more than one method.
It looks fishy to me. I think the reason you're ending up having to do this is a design flaw. Your method that needs to be "split" probably does too much. The solution would be to break it up in steps, and give that "doSubclassSpecificStuff" step a specific meaning.
For ex.:
void Live()
{
BeBorn();
DoCrazyStuff(); // this can be made protected virtual
Die();
}
Yes, it's perfectly fine. This is an example of the Template Method pattern, where you use inheritance to define a method that maintains a known "skeleton", but can have custom logic.
public abstract class Ancestor
{
protected virtual void CanOverrideThisStep(){...}
protected abstract void MustDefineThisStep();
protected sealed void MustDoExactlyThis(){...}
private void HideThisStepFromEveryone(){...}
public sealed void TemplateMethod()
{
...
CanOverrideThisStep();
...
MustDoExactlyThis();
...
MustDefineThisStep();
...
HideThisStepFromEveryone();
}
}
Inheritors of Ancestor above must define a body for MustDefineThisStep(), and may at their option override CanOverrideThisStep(), but cannot touch MustDoExactlyThis(), HideThisStepFromEveryone, or the TemplateMethod driving function itself. However, except for HideThisStepFromEveryone, all the submethods are available to child classes, so a child may use MustDoExactlyThis() in the implementation of MustDefineThisStep().
This is very common; such constructions are the reason OO languages have such access modifiers such as these at their disposal. The pattern is very useful for workflows, file processing, and other tasks that are generally the same but have slightly different implementation details.
I routinely use this technique as a way to handle special cases. I'll write things like this:
public void foo()
{
theData=getTheData();
preprocessDataHook(theData);
putTheData(theData);
}
protected void preprocessDataHook(SomeObject theData)
{
// Nop. Available for subclasses to override.
}
A subclass that does not need to preprocess the data can then just not override this function. A subclass that does need to preprocess can override the function.
If we expected that all or most subclasses would need to preprocess, then this should be an abstract function to force the programmer to implement it, or make a conscious decision to do nothing. But if it's just an occassional subclass that needs to do something here, I think this is a perfectly valid approach.
Should methods in a Java interface be declared with or without the public access modifier?
Technically it doesn't matter, of course. A class method that implements an interface is always public. But what is a better convention?
Java itself is not consistent in this. See for instance Collection vs. Comparable, or Future vs. ScriptEngine.
The JLS makes this clear:
It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface.
The public modifier should be omitted in Java interfaces (in my opinion).
Since it does not add any extra information, it just draws attention away from the important stuff.
Most style-guides will recommend that you leave it out, but of course, the most important thing is to be consistent across your codebase, and especially for each interface. The following example could easily confuse someone, who is not 100% fluent in Java:
public interface Foo{
public void MakeFoo();
void PerformBar();
}
Despite the fact that this question has been asked long time ago but I feel a comprehensive description would clarify why there is no need to use public abstract before methods and public static final before constants of an interface.
First of all Interfaces are used to specify common methods for a set of unrelated classes for which every class will have a unique implementation. Therefore it is not possible to specify the access modifier as private since it cannot be accessed by other classes to be overridden.
Second, Although one can initiate objects of an interface type but an interface is realized by the classes which implement it and not inherited. And since an interface might be implemented (realized) by different unrelated classes which are not in the same package therefore protected access modifier is not valid as well. So for the access modifier we are only left with public choice.
Third, an interface does not have any data implementation including the instance variables and methods. If there is logical reason to insert implemented methods or instance variables in an interface then it must be a superclass in an inheritance hierarchy and not an interface. Considering this fact, since no method can be implemented in an interface therefore all the methods in interface must be abstract.
Fourth, Interface can only include constant as its data members which means they must be final and of course final constants are declared as static to keep only one instance of them. Therefore static final also is a must for interface constants.
So in conclusion although using public abstract before methods and public static final before constants of an interface is valid but since there is no other options it is considered redundant and not used.
With the introduction of private, static, default modifiers for interface methods in Java 8/9, things get more complicated and I tend to think that full declarations are more readable (needs Java 9 to compile):
public interface MyInterface {
//minimal
int CONST00 = 0;
void method00();
static void method01() {}
default void method02() {}
private static void method03() {}
private void method04() {}
//full
public static final int CONST10 = 0;
public abstract void method10();
public static void method11() {}
public default void method12() {}
private static void method13() {}
private void method14() {}
}
I disagree with the popular answer, that having public implies that there are other options and so it shouldn't be there. The fact is that now with Java 9 and beyond there ARE other options.
I think instead Java should enforce/require 'public' to be specified. Why? Because the absence of a modifier means 'package' access everywhere else, and having this as a special case is what leads to the confusion. If you simply made it a compile error with a clear message (e.g. "Package access is not allowed in an interface.") we would get rid of the apparent ambiguity that having the option to leave out 'public' introduces.
Note the current wording at: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4
"A method in the body of an interface may be declared public or
private (§6.6). If no access modifier is given, the method is implicitly public. It is permitted, but discouraged as a matter of
style, to redundantly specify the public modifier for a method
declaration in an interface."
See that 'private' IS allowed now. I think that last sentence should have been removed from the JLS. It is unfortunate that the "implicitly public" behaviour was ever allowed as it will now likely remain for backward compatibilty and lead to the confusion that the absence of the access modifier means 'public' in interfaces and 'package' elsewhere.
I always write what I would use if there was no interface and I was writing a direct implementation, i.e., I would use public.
I would avoid to put modifiers that are applied by default. As pointed out, it can lead to inconsistency and confusion.
The worst I saw is an interface with methods declared abstract...
I used declare methods with the public modifier, because it makes the code more readable, especially with syntax highlighting. In our latest project though, we used Checkstyle which shows a warning with the default configuration for public modifiers on interface methods, so I switched to ommitting them.
So I'm not really sure what's best, but one thing I really don't like is using public abstract on interface methods. Eclipse does this sometimes when refactoring with "Extract Interface".
The reason for methods in interfaces being by default public and abstract seems quite logical and obvious to me.
A method in an interface it is by default abstract to force the implementing class to provide an implementation and is public by default so the implementing class has access to do so.
Adding those modifiers in your code is redundant and useless and can only lead to the conclusion that you lack knowledge and/or understanding of Java fundamentals.
I prefer skipping it, I read somewhere that interfaces are by default, public and abstract.
To my surprise the book - Head First Design Patterns, is using public with interface declaration and interface methods... that made me rethink once again and I landed up on this post.
Anyways, I think redundant information should be ignored.
It's totally subjective. I omit the redundant public modifier as it seems like clutter. As mentioned by others - consistency is the key to this decision.
It's interesting to note that the C# language designers decided to enforce this. Declaring an interface method as public in C# is actually a compile error. Consistency is probably not important across languages though, so I guess this is not really directly relevant to Java.
People will learn your interface from code completion in their IDE or in Javadoc, not from reading the source. So there's no point in putting "public" in the source - nobody's reading the source.