88

I have a basic question in Java, but it's a general question in OOP. Why do interfaces allow fields to be set? Doesn't that run contrary to what an interface is supposed to do?

The way I made sense of it, an interface is what in English would be an adjective. So, if my class implements the interfaces Runnable and Serializable, I'm ensuring the user that my class will satisfy the conditions to be Runnable and Seriablizable. However, that would mean interfaces are "stateless", but they are allowed to have fields in Java...

Am I missing something?

Sal
  • 3,179
  • 7
  • 31
  • 41
  • In c#, you can use an interface to implement a *property*, which behaves similar to a getter/setter method in java, but is frequently treated like a class member. – cr1pto May 03 '20 at 05:13

5 Answers5

108

All fields in interface are public static final, i.e. they are constants.

It is generally recommended to avoid such interfaces, but sometimes you can find an interface that has no methods and is used only to contain list of constant values.

jameshfisher
  • 34,029
  • 31
  • 121
  • 167
Andrew Logvinov
  • 21,181
  • 6
  • 52
  • 54
  • 1
    I saw this only for j2me where is Java 1.3 – Eugen Martynov Dec 17 '12 at 08:39
  • 1
    Why would you say that interfaces with constants are avoided? – Georgian Jan 06 '14 at 08:41
  • 3
    Answering for , "Why would you say that interfaces with constants are avoided" , because designwise its not good practise, if you want to define constants, simply create an Enum class and define them there, its more logical and neat. In my opinion it does not make sense to implement an interface to make use of the constants, thats bloated code. – Amos Kosgei Oct 27 '18 at 09:42
  • Could you share any reference? Doc url maybe. – Muhammed Ozdogan Feb 05 '20 at 17:23
  • 1
    @MuhammedOzdogan , you can see item 22: "Use interfaces only to define types" of "Effective Java" : "The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class’s exported API." – FraK Jul 27 '20 at 13:37
  • defaults change everything... not that defaults were a bad idea..., they were a necessity. private constants inside an interface would make it possible to define preestablished default states. An example would be myFunction = UnaryOperator.identity(), could now be inferred with myFunction.isIdentity(), by having a private static final Function privateIdentity;... and then default boolean isIdentity() {return this == privateIdentity;} All types of default behaviors are characterized by a constant used/unused parameter, that the client should not care about. – Delark Jun 06 '22 at 16:07
28

First of all, there's difference between OOP paradigm and OOP implementation in Java, so same words may mean a bit different things.

In OOP the paradigm interface is what you can do with the object (or what object can do for you). Any object can have several interfaces and thus play different roles. For example, someone may work as a programmer and be able to create programs, but at the same time he may be a husband and father and thus be able to pay the bills for his family and take care of children. Here "programmer", "husband" and "father" are interfaces, and a person is an object that implements them. Note, that interfaces do not imply presence of any specific features (fields) for implementing object, just actions that this object should be able to perform.

Java more or less follows this idea, but as any paradigm implementation has its own features. Java allows describing methods, that is actions that the implementing object should be able to perform, but not any implementation details, thus, nothing about object fields or private methods.

But what about constants (public final static fields)? Are they part of implementation or interface. It could be both. E.g. interface "programmer" can have constant WORK_HOURS set to "8". Thus Java allows you to describe constants in interfaces too.

Note, that Java only helps you to make good OOP design, but it doesn't strongly require it. In particular, not all public methods of an object should exist in interface too. For example, getter and setter methods are normally public, but in fact they are the part of implementation, not interface, and thus it's worth not to bring them into interface.

(Please also note, that most things I described here are about mainstream OOP like in Java, but there are also other kinds of OOP such as prototype-based one, in particular implemented in JavaScript).

ffriend
  • 27,562
  • 13
  • 91
  • 132
8

What if that interface refers to constants? Wouldn't it be natural to declare them in the interface?

interface IdFinder {
    Serializable UNSAVED = new Serializable() {};

    /** @returns the given entity's persistent identity, 
                 or {@link UNSAVED} if it hasn't been saved yet, 
                 or null if o is a value object that hasn't a 
                 persistent identity of its own.
     */
    Serializable getId(Object o);
}
meriton
  • 68,356
  • 14
  • 108
  • 175
3

Yes, you can have constant fields in interfaces, but you are right when you say that "it seems contrary to what an interface is supposed to do", as it is not a good practice. Why would you want to have all your classes that implement an interface with the same constants? You could simply have them in the class that uses them, or if you really need to export them somehow, have them in a separate class utiliy like this:

public class Constants {
    private Constants() { }

    public static final int ZERO = 0;
    public static final int SOME_COMPLEX_NUM = 2124132L;
    ...
}

You also have enums, if you need to represent a set of constant fields with some meaning. I do not see any "use case" where you would actually need constants in an interface. But could be wrong :)

jlemos
  • 526
  • 4
  • 13
0

While other answers explain the theory, I just wanted to give you a 'production' example of an interface that has fields - you can find it in javax.servlet.ServletContext.
There is such field:

  /**
   * The name of the ServletContext attribute that holds the temporary file
   * location for the web application.
   */
  public static final String TEMPDIR = "javax.servlet.context.tempdir";
william xyz
  • 710
  • 5
  • 19
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 05 '23 at 22:50