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.:
public interface Rectangle {
int height = 0;
int width = 0;
public int getHeight();
public int getWidth();
public void setHeight(int height);
public void setWidth(int width);
}
public class Tile implements Rectangle{
#Override
public int getHeight() {
return 0;
}
#Override
public int getWidth() {
return 0;
}
#Override
public void setHeight(int height) {
}
#Override
public void setWidth(int width) {
}
}
In the above method how can we compel Tile class to declare height and width attributes using the interface? For some reason I wish to do it with interface only!
I initially thought of using it with inheritance.
But thing is I have to deal with 3 classes.!
Rectangle
Tile
JLabel.!
class Tile extends JLabel implements Rectangle {}
would work.!
but
class Tile extends JLabel extends Rectangle {}
woud not.!
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
{
}
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.
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.
In Java you can't. Interface has to do with methods and signature, it does not have to do with the internal state of an object -- that is an implementation question. And this makes sense too -- I mean, simply because certain attributes exist, it does not mean that they have to be used by the implementing class. getHeight could actually point to the width variable (assuming that the implementer is a sadist).
(As a note -- this is not true of all languages, ActionScript allows for declaration of pseudo attributes, and I believe C# does too)
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").
Like everyone says, you cannot add attributes to an interface.
But, I follows this answer: https://stackoverflow.com/a/25907755/12955288
You can use an service with a WeakHashMap to store attributes.
To reduce maps, use a Map of keys like this:
In java 11:
public interface Rectangle {
class Storage {
private static final Map<Rectangle, Map<String, Object>> attributes = new WeakHashMap<>();
}
private Map<String, Object> getAttributes(){
return Storage.attributes.computeIfAbsent(this, k -> new HashMap<>());
}
default public int getHeight() {
return (int) getAttributes().getOrDefault("height", 0);
}
default public int getWidth() {
return (int) getAttributes().getOrDefault("width", 0);
}
default public void setHeight(int height) {
getAttributes().put("height", height);
}
default public void setWidth(int width) {
getAttributes().put("width", width);
}
}
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).
For interfaces with member variables, use an abstract class:
public abstract class Rectangle {
int height = 0;
int width = 0;
public abstract int getHeight();
public abstract int getWidth();
public abstract void setHeight(int height);
public abstract void setWidth(int width);
}
An ancillary point:
I always thought declaring attributes in an interface is sort of an anti-pattern as interfaces are stateless. And I haven't had a practical use case for it until I required dependency injection on all the concrete classes implementing the interface. While I could manually inject the dependencies on each class, it would be easier to inherit them from a parent class.
So, as many people have already mentioned, using an Abstract class is the way to go where the dependency can be injected (#Inject), and all the child classes could extend this and override (#Override) the methods while using the attributes of the parent class.
Related
I'm currently learning Java so please bear with my ignorance. Here is my current code
Shape.java
public interface Shape {
public abstract void draw();
}
Rectangle.java
public abstract class Rectangle implements Shape {
private final double width, length;
public Rectangle() {
this(1,1);
}
public Rectangle(double width, double length) {
this.width = width;
this.length = length;
}
public void draw() {
System.out.println("A rectangle of sides " + length + " by " + width + " will be drawn");
}
}
TestPolymorph.java
public class TestPolymorph implements Shape {
public static void main(String[] args) {
Shape[] drawObject = { new Rectangle(40, 60) };
drawObject[0].draw();
}
#Override
public void draw() {
// TODO Auto-generated method stub
}
}
Is there anything wrong with my current code since it's not working. My question is how can I create a drawObject instance that belongs to Shape class and during runtime drawObjectwill be created with two arguments, length and width (giving 40 and 60 for example), draw method of Rectangle will then be invoked.
You're close, there really isn't any need to have your TestPolymorph implement Shape. That is your driver, not a model implementing an interface so you could take that off.
Lastly, remove the abstract from the Rectangle class. That is not an abstract class because you actually want an instance of that type.
Try to remove the abstract modifier from the Rectangle object. You also don't need to implement the Shape interface in TestPolymorph.java
Shape[] drawObject = { new Rectangle(40, 60) };
above is your code
Shape[] drawObject = { new Rectangle(40, 60) {} };
this is correct code
since you are creating objects of abstract class you have to go with this
approach. or you can just remove abstract modifier from Rectangle class
if you are creating a object of abstract class you are forced to implement all its abstract methods , since you dont have any abstract method inside your abstract rectangle class you just have to new Rectangle(40, 60) {}
pass empty brackets at the end bt if your class has abstract methods inside the brackets you have to implement the abstract method
Improving Interface
Every method declaration in the body of an interface is implicitly public and abstract.
Ref: http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.4
Make it simple. Rather than complicating the things.
Just go in a valid inherited manner.
Remove the abstract from Rectangle class and also there is no need for TestPolymorph to implement the Shape interface.
Rectangle implements the Shape interface and just Test Polymorphism in TestPolymorph.
I'm currently in a Java-based university class and for coding samples the professor is using protected fields for the subclasses to access.
I asked if this was bad practice and was told it is normal. Is this true, why not use setters and getters for abstract methods? I thought it was always best practice to restrict as much information as possible unless required otherwise.
I tested out using setters and getters with abstract parent and it works fine for abstract parent classes that are subclassed. Although abstract classes cannot be instantiated, they can still be used to create objects when a subclass is instantiated as far as I understand.
Here is a short example:
public abstract class Animal {
protected int height;
}
public class Dog extends Animal {
public Dog() {
height = 6;
}
}
public class Cat extends Animal {
public Cat() {
height = 2;
}
}
As opposed to using:
public abstract class Animal {
private int height;
public getHeight() {
return height;
}
public setHeight(int height) {
this.height = height;
}
}
public class Dog extends Animal {
public Dog() {
setHeight(6);
}
}
public class Cat extends Animal {
public Cat() {
setHeight(2);
}
}
While you can certainly do both ways the protected field way is less desirable and I would argue less idiomatic particularly if this is library code that you plan to share.
You can see this in the Java Collections API as well as Guava. You will be hard pressed to find Abstract classes that have protected fields (let alone any fields).
That being said there are always exceptions and you are not always writing library code (ie public api).
Here is my opinion on protected and/or private fields and abstract classes. If you are going to do it than make a constructor that takes the initial values:
public abstract class Animal {
private int height;
public Animal(int height) { this.height = height; }
public int getHeight() { return this.height }
}
public class Cat extends Animal {
public Cat() {
super(2);
}
}
Now your subclasses are required to set height to something as they have to call the constructor that takes height.
In your first example, only subclasses of Animal can access the protected field height.
In you second example, any class whatsoever can manipulate the field height indirectly via the public setter method.
See the difference?
I like consolidating my code/classes as much as possible without each class itself getting messy. So I looked into using NestedClasses, though InnerClasses in this case because the InnerClass needs access the OuterClass's members.
Example
Lets say I have a program that calculates various shape attributes to shapes. So given a Rectangle Shape, it would find the Area/Perimeter from inputs of length and width.
I would first create an abstract class Shape, which has abstract methods getArea() and getPerimeter(). I would then create my subclass RectangleShape, extend the shape class, #Override those methods with the necessary logic.
Now there's a shape Rectangular Prism (Cube). It has the same variables/methods as RectangleShape does, but with one extra, height. In the past I would create another subclass of RectangleShape and go from there.
Is it better/not worse to use an InnerClass instead and have an abstract class PrismShape? I ask this because Prisms share the same methods, no matter the shape. If you're at all confused by the above I'm posting code below of what I'm saying.
Example Code
Shape Class
public abstract class Shape {
public abstract double getArea();
public abstract double getPerimeter();
}
PrismShape Class
public abstract class PrismShape{
public abstract double getVolume();
public abstract double getSurfaceArea();
public abstract double getLateralArea();
}
RectangleShape Class
import Abstract.Shape;
import Abstract.ShapePrism;
public class RectangleShape extends Shape{
//Variables Declared
private double _length, _width;
//Constructor
public RectangleShape(double _length, double _width) {
setLength(_length);
setWidth(_width);
}
//Getters and Setters
#Override
public double getArea() {
return getLength() * getWidth();
}
#Override
public double getPerimeter() {
return (2 * getLength())+ (2 * getWidth());
}
public double getLength() {
return _length;
}
private void setLength(double _length) {
this._length = _length;
}
public double getWidth() {
return _width;
}
private void setWidth(double _width) {
this._width = _width;
}
//Inner Class Prism
public class RecPrismShape extends PrismShape{
//Variables Declared
private double _height;
//Constructor
public RecPrismShape(double _height) {
setHeight(_height);
}
//Getters and Setters
#Override
public double getSurfaceArea(){
return (getLateralArea() + (2 * getArea()));
}
#Override
public double getVolume(){
return getArea() * getHeight();
}
#Override
public double getLateralArea(){
return getPerimeter() * getHeight();
}
public double getHeight() {
return _height;
}
private void setHeight(double _height) {
this._height = _height;
}
}
}
I'm open to criticism, still fairly new to Java. My thought process during this was I have 2d Shape attributes and 3d (Prism) shape attributes. The 3d Shapes derive their attributes from 2d shapes, but not visa versa. So for me at least having InnerClasses makes sense.
My own take on this: A public inner class seems most useful when the rest of the program has an object of the outer class, and it wants to create an object of the inner class that "belongs" to the outer class object in some way; that is, it's tightly associated with it.
The way you've arranged things, however, it means that if the client wants to create a RecPrismShape object, it has to first create a RectangleShape object that the prism object will belong to. Most likely, this is not going to be useful. That is, the client creates a RectangleShape rect just because it has to, in order to create a RecPrismShape, and the rect object wouldn't be useful to it in any other way.
I think a better idea would be to have a RecPrismShape object have a private RectangleShape object as one of its fields, but this would be an "implementation detail". That way, you'd get to reuse the RectangleShape code, which it seems like you're trying to do.
public class RecPrismShape extends RectangleShape {
private RectangleShape rect;
private double height;
public RecPrismShape(double length, double width, double height) {
rect = new RectangleShape(length, width);
this.height = height;
}
// and just one example of how you could use it
public double getVolume() {
return rect.getArea() * getHeight();
}
}
I am experience some problems in understanding how the OO pattern works, My lecturer gave me the following question but I cannot solve it after thinking whole day
Scenario for my problems.
There is a class named "ShapeManager" which manages the Shape object. A class named "Shape" has two subclasses named "Circle" and "Rectangle"
The implementation of Shape class as follow
abstract public class Shape {
private String id;
private double length;
public Shape() {
}
public Shape(String id , double length) {
this.id = id;
this.length = length;
}
public void setID(String id) {
this.id = id;
}
public String getID() {
return id;
}
public void setLength(double length) {
this.length = length;
}
public double getLength() {
return length;
}
public abstract String getDetails();
}
The subclass Square as follow
public class Square extends Shape{
public Square() {
super();
}
public Square(String id , double side) {
super(id, side);
}
#Override
public String getDetails() {
return "Square => Id : "+getID() +", Side : "+ getLength() + ",Area : "+(getLength() * getLength());
}
}
The subclass Circle as follow
public class Circle extends Shape{
public Circle(){
super();
}
public Circle (String id, double radius) {
super(id, radius);
}
#Override
public String details() {
return "Circle => Id : "+getID() + ", Radius : "+ getLength() + ",Area: "+(3.14*(getLength() * getLength()));
}
}
The ShapeManager class as follow, this is not a completed class
public class ShapeManager {
public Shape createShape() {
}
public void updateLength(String id ){
}
public void deleteShape(String id) {
}
public void listShapes() {
}
}
ShapeManager have an association with Shape
ShapeManager --1------0..*--> Shape
The design of this package (All the classes above) can not be changed, implementation must be following OCP (Open-Closed Principle).
My question is: How am I suppose to complete createShape method? Without parameter, it is seemingly impossible to create an object either a Rectangle or Circle.
ShapeManager cannot create a shape if not knowing what this shape is (Square, Circle or something else). And it really doesn't know because you say the method createShare has no parameters. Either you misunderstood the question or the lecturer didn't explain it well. You should ask him/her for clarifications. If you look at the libraries of Java or any other OO language, I am pretty sure you won't find such scenario and implementation pattern as the one you gave in your example.
#croraf
You should find some other reading I think e.g. the classic book http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612. The main idea of a factory is that it returns something whose type the caller doesn't know, and doesn't care about. For example, if you have a method createSocket() in some SocketFactory, this method is usually defined to return an interface or an abstract class Socket. But actually it returns new SocketImpl1() and new SocketImpl2() which are concrete classes. What the factory returns may depend on many things - a system property, the underlying OS, anything you can think of. The main idea is that the factory centralizes the creation of Socket objects at one single place. This way, if you need to make a change, you can make it just in the factory. I think this book also has some decent Java counterparts too, you may look around. Other free good sources are referenced here.
Real world examples of Factory Method pattern
I think you should have something like this, similar to how BorderFactory from java API works.
public class ShapeManager {
public Shape createCircle() {
...
return Circle;
}
public Shape createSquare() {
....
return Square;
}
...
public void updateLength(String id ){
}
public void deleteShape(String id) {
}
public void listShapes() {
}
}
You can't create shape without knowing type which shape would You like to create. You can define enumeration for types and pass the type value to the createShape(). And there You can switch between types and create the concrette shape You want.
For me, Its classic Factory pattern.
public class ShapeFactory {
public abstract Shape getShape(int shapeId);
}
public interface Const {
public static final int SHAPE_CIRCLE =1;
public static final int SHAPE_SQUARE =2;
}
public class SimpleShapeFactory extends ShapeFactory throws BadShapeException {
public Shape getShape(int shapeTypeId){
Shape shape = null;
if(shapeTypeId == Const.SHAPE_CIRCLE) {
//in future can reuse or cache objects.
shape = new Circle();
}
else if(shapeTypeId == Const.SHAPE_SQUARE) {
//in future can reuse or cache objects
shape = new Square();
}
else throw new BadShapeException("ShapeTypeId="+ shapeTypeId);
return shape;
}
}
Calling:
ShapeFactory factory = new SimpleShapeFactory();
//returns a Shape but whether it is a Circle or a
//Square is not known to the caller.
Shape s = factory.getShape(1);
s.getDetails(); // circle details called
//returns a Shape but whether it is a Circle or a
//Square is not known to the caller.
s = factory.getShape(2);
s.getDetails(); //Square details called
References:
The Open Close Principle states that the design and writing of the code should be done in a way that new functionality should be added with minimum changes in the existing code. The design should be done in a way to allow the adding of new functionality as new classes, keeping as much as possible existing code unchanged.
I have this code :
public interface Position {
public int getX();
public int setX(int x);
public int getY();
public int setY(int y);
}
public StandardPosition implements Position {
// STANDARD implementation of Position here
}
public abstract class Mover {
public abstract Position move ( Position originalPosition );
}
A "Mover" is something that moves something from an initial position to a final position.
Now here's the interesting part ... some movers are more complicated and work with Position objects that are a bit more complicated.
public class ComplicatedPosition extends StandardPosition {
// ADDS Y DIMENSION
private int y;
public int getY() { return(y); }
public void setY(int y) { this.y = y ; }
}
public class MoreComplicatedMover extends Mover {
#Override
public void Position move(Position initialPosition) {
ComplicatedPosition q = (ComplicatedPosition) initialPosition;
// Do a transformation and
// return a new position
return(q);
}
}
My question here is ...is there any way to avoid casting from the Position to ComplicatedPosition ...(we are casting from interface to class .. seems a bit awkward ) ...
Another way of asking this question is : is there any other way to set up this code ?
Cheers !
Well one thing you could do is use generics like:
public abstract class Mover<T extends Position> {
public abstract T move(T originalPosition );
}
public class ComplicatedMover extends Mover<ComplicatedPosition> {
public ComplicatedPosition move(ComplicatedPosition p) {
//do stuff
}
}
However I'm not sure if this is what you should want.
btw; is your Mover supposed to give a new Position or alter the given Position?
Personally I would make it a void method if you are altering the given Position.
If the API for ComplicatedPosition is different with StandardPosition (which I assume it is and that is the reason why you are casting), update your Position interface and put all needed APIs in there. Then, first approach would be implementing those extra methods in StandardPosition and simply putting
throw new UnsupportedOperationException("");
A better approach is to implement adapter pattern and have an abstract class like PositionAdapter which implements all those extra methods and throws the UnsupportedOperationException and then have
public class StandardPosition extends PositionAdapter {
}
This way you won't have to implement a bunch of not needed methods in your StandardPosition or any other implementing classes. Then you can get rid of your castings and call all methods on interface.
Hope this helps.