Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Interface Usage Guidelines -- Are getters and setters in an interface bad?

What do people think of the best guidelines to use in an interface? What should and shouldn't go into an interface?

I've heard people say that, as a general rule, an interface must only define behavior and not state. Does this mean that an interface shouldn't contain getters and setters?

My opinion: Maybe not so for setters, but sometimes I think that getters are valid to be placed in an interface. This is merely to enforce the implementation classes to implement those getters and so to indicate that the clients are able to call those getters to check on something, for example.

like image 834
His Avatar asked Jul 15 '09 09:07

His


People also ask

Can we use getter and setter in interface?

You cannot define instance fields in interfaces (unless they are constant - static final - values, thanks to Jon), since they're part of the implementation only. Thus, only the getter and setter are in the interface, whereas the field comes up in the implementation.

Are getters and setters bad practice?

Getter and setter methods (also known as accessors) are dangerous for the same reason that public fields are dangerous: They provide external access to implementation details. What if you need to change the accessed field's type? You also have to change the accessor's return type.

Do getters and setters enforce or weaken encapsulation?

Having getters and setters does not in itself break encapsulation.

Should setters and getters be public?

Usually you want setters/getters to be public, because that's what they are for: giving access to data, you don't want to give others direct access to because you don't want them to mess with your implementation dependent details - that's what encapsulation is about.


2 Answers

I don't see why an interface can't define getters and setters. For instance, List.size() is effectively a getter. The interface must define the behaviour rather than the implementation though - it can't say how you'll handle the state, but it can insist that you can get it and set it.

Collection interfaces are all about state, for example - but different collections can store that state in radically different ways.

EDIT: The comments suggest that getters and setters imply a simple field is used for backing storage. I vehemently disagree with this implication. To my mind there's an implication that it's "reasonably cheap" to get/set the value, but not that it's stored as a field with a trivial implementation.


EDIT: As noted in the comments, this is made explicit in the JavaBeans specification section 7.1:

Thus even when a script writer types in something such as b.Label = foo there is still a method call into the target object to set the property, and the target object has full programmatic control.

So properties need not just be simple data fields, they can actually be computed values. Updates may have various programmatic side effects. For example, changing a bean’s background color property might also cause the bean to be repainted with the new color."


If the supposed implication were true, we might just as well expose properties as fields directly. Fortunately that implication doesn't hold: getters and setters are perfectly within their rights to compute things.

For example, consider a component with

getWidth() getHeight() getSize() 

Do you believe there's an implication that there are three variables there? Would it not be reasonable to either have:

private int width; private int height;  public int getWidth() {     return width; }  public int getHeight() {     return height; }  public Size getSize() {     return new Size(width, height); // Assuming an immutable Size type } 

Or (preferrably IMO):

private Size size;  public int getWidth() {     return size.getWidth(); }  public int getHeight() {     return size.getHeight(); }  public Size getSize() {     return size; } 

Here either the size property or the height/width properties are for convenience only - but I don't see that that makes them invalid in any way.

like image 131
Jon Skeet Avatar answered Sep 28 '22 08:09

Jon Skeet


I think that there are two types of interfaces declared in general:

  1. a service description. This might be something like CalculationService. I don't think that methods getX should be in this sort of interface, and certainly not setX. They quite clearly imply implementation detail, which is not the job of this type of interface.
  2. a data model - exists solely to abstract out the implementation of data objects in the system. These might be used to aid in testing or just because some people as old as me remember the days when (for example) using a persistence framework tied you down to having a particular superclasss (i.e. you would choose to implement an interface in case you switched your persistence layer). I think that having JavaBean methods in this type of interface is entirely reasonable.

Note: the collections classes probably fit in to type #2

like image 40
oxbow_lakes Avatar answered Sep 28 '22 10:09

oxbow_lakes