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.