I wish to know is there any way in which I can make it compulsory for the implementer class to declare the objects handles/primitives as they do with methods. for e.g.:
Something important has been said by Tom:
if you use the has-a concept, you avoid the issue.
Indeed, if instead of using extends and implements you define two attributes, one of type rectangle, one of type JLabel
in your Tile
class, then you can define a Rectangle
to be either an interface or a class.
Furthermore, I would normally encourage the use of interfaces in connection with has-a, but I guess it would be an overkill in your situation. However, you are the only one that can decide on this point (tradeoff flexibility/over-engineering).
Interfaces cannot require instance variables to be defined -- only methods.
(Variables can be defined in interfaces, but they do not behave as might be expected: they are treated as final static
.)
Happy coding.
Java 8 introduced default methods for interfaces using which you can body to the methods. According to OOPs interfaces should act as contract between two systems/parties.
But still i found a way to achieve storing properties in the interface. I admit it is kinda ugly implementation.
import java.util.Map;
import java.util.WeakHashMap;
interface Rectangle
{
class Storage
{
private static final Map<Rectangle, Integer> heightMap = new WeakHashMap<>();
private static final Map<Rectangle, Integer> widthMap = new WeakHashMap<>();
}
default public int getHeight()
{
return Storage.heightMap.get(this);
}
default public int getWidth()
{
return Storage.widthMap.get(this);
}
default public void setHeight(int height)
{
Storage.heightMap.put(this, height);
}
default public void setWidth(int width)
{
Storage.widthMap.put(this, width);
}
}
This interface is ugly. For storing simple property it needed two hashmaps and each hashmap by default creates 16 entries by default. Additionally when real object is dereferenced JVM additionally need to remove this weak reference.
Fields in interfaces are implicitly public static final
. (Also methods are implicitly public, so you can drop the public
keyword.) Even if you use an abstract class instead of an interface, I strongly suggest making all non-constant (public static final
of a primitive or immutable object reference) private
. More generally "prefer composition to inheritance" - a Tile
is-not-a Rectangle
(of course, you can play word games with "is-a" and "has-a").
The point of an interface is to specify the public API. An interface has no state. Any variables that you create are really constants (so be careful about making mutable objects in interfaces).
Basically an interface says here are all of the methods that a class that implements it must support. It probably would have been better if the creators of Java had not allowed constants in interfaces, but too late to get rid of that now (and there are some cases where constants are sensible in interfaces).
Because you are just specifying what methods have to be implemented there is no idea of state (no instance variables). If you want to require that every class has a certain variable you need to use an abstract class.
Finally, you should, generally speaking, not use public variables, so the idea of putting variables into an interface is a bad idea to begin with.
Short answer - you can't do what you want because it is "wrong" in Java.
Edit:
class Tile
implements Rectangle
{
private int height;
private int width;
@Override
public int getHeight() {
return height;
}
@Override
public int getWidth() {
return width;
}
@Override
public void setHeight(int h) {
height = h;
}
@Override
public void setWidth(int w) {
width = w;
}
}
an alternative version would be:
abstract class AbstractRectangle
implements Rectangle
{
private int height;
private int width;
@Override
public int getHeight() {
return height;
}
@Override
public int getWidth() {
return width;
}
@Override
public void setHeight(int h) {
height = h;
}
@Override
public void setWidth(int w) {
width = w;
}
}
class Tile
extends AbstractRectangle
{
}
You can only do this with an abstract class, not with an interface.
Declare Rectangle
as an abstract class
instead of an interface
and declare the methods that must be implemented by the sub-class as public abstract
. Then class Tile
extends class Rectangle
and must implement the abstract methods from Rectangle
.