Polymorphism




Polymorphism is the ability of a general object to behave as a specific object. Super class references (pointers) can refer (point) to a subclass, but subclass references (pointers) cannot refer (point) to a super class. (a parent can point to a child, but a child cannot point to a parent)

Examples:


// here the Object pointer s is a general thing, 
// but s.toString() is behaving as a specific object (String)
Object s = "Hello World";  // Object s pointing to a String object
System.out.println(s.toString()); // the call toString() is the String's method

In order for this to compile, any method calls made by s must exist at the
Object level (or above).

// the statement below would fail to compile 
// since Object does not contain a substring() method.
System.out.println(s.substring(1)); 


Example with Shapes:

The following example shows how you could make a bunch of shape objects, like a Rectangle, Line, Ellipse, Star, etc. All of these shapes have things in common. So, we can put all of the common methods and constants into an interface, and then all of the common instance variables into an abstract class where we would write all of our methods that we know how to write. Finally, we could write our actual Shape classes. ShapeInterface define common constants and methods | | AbstractShapeObject define common instance variables | | | | define and write constructors | | | | and write what we can | | | | Rectangle Ellipse Line etc. define any unique instance variables define and write constructors write any unwritten methods from above define and write any unique methods We could define: ArrayList<AbstractShapeObject> list = new ArrayList<AbstractShapeObject>(); We could then create specific shape objects and add them to our list: AbstractShapeObject myShape; myShape = new Line(x1,y1,x2,y2,color); myShape.setMode("Line"); list.add(myShape); myShape = new Rectangle(x1,y1,x2,y2,color); myShape.calcXYWidthHeight(x1,y1,x2,y2); myShape.setMode("Rectangle"); list.add(myShape); // etc. We could draw specific shape objects: for (int j=0; j < myList.size(); j++) { AbstractShapeObject myShape = myList.get(j); // polymorphism in action // a general object acting like a specific object myShape.draw(gMemory); }
import java.awt.*; import java.awt.geom.*; interface ShapeInterface { // all variables (constants) are public static final by default public int defaultWidth = 1; public int defaultHeight = 1; public int defaultThickness = 1; public Color defaultColor = Color.RED; // these methods are all public abstract by default public int getX(); public void setX(int x); public int getY(); public void setY(int y); public int getWidth(); public void setWidth(int width); public int getHeight(); public void setHeight(int height); public int getThickness(); public void setThickness(int thickness); public Color getColor(); public void setColor(Color color); public String getMode(); public void setMode(String mode); public boolean getKeep(); public void setKeep(boolean keep); public abstract void draw(Graphics window); } abstract class AbstractShapeObject implements ShapeInterface { private int x; private int y; private int width; private int height; private Color color; private int thickness; private String mode; // Am I a Rectangle, Line, etc. private boolean keep; // do I keep the shape or erase it later public AbstractShapeObject() { this(0,0,0,0,defaultThickness,defaultColor); } public AbstractShapeObject(int x, int y) { this(x,y,defaultWidth,defaultHeight,defaultThickness,defaultColor); } public AbstractShapeObject(int x, int y, Color color) { this(x,y,defaultWidth,defaultHeight,defaultThickness,color); } public AbstractShapeObject(int x, int y, int thickness) { this(x,y,defaultWidth,defaultHeight,thickness,defaultColor); } public AbstractShapeObject(int x, int y, int thickness, Color color) { this(x,y,defaultWidth,defaultHeight,thickness,color); } public AbstractShapeObject(int x, int y, int width, int height) { this(x,y,width,height,defaultThickness,defaultColor); } public AbstractShapeObject(int x, int y, int width, int height, Color color) { // call this(?????) (the constructor with all the parameters below) this(x,y,width,height,defaultThickness,color); } public AbstractShapeObject(int x, int y, int width, int height, int thickness) { // call this(?????) (the constructor with all the parameters below) this(x,y,width,height,thickness,defaultColor); } public AbstractShapeObject(int x, int y, int width, int height, int thickness, Color color) { this.x = x; this.y = y; this.width = width; this.height = height; this.color = color; this.thickness = thickness; mode = "None"; keep = true; } // write all of your getter and setter methods here !!! // do NOT write your draw methods here // you will write your draw methods in the specific classes // since you don't really know what to draw here public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public int getThickness() { return thickness; } public void setThickness(int thickness) { this.thickness = thickness; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } public String getMode() { return mode; } public void setMode(String mode) { this.mode = mode; } public boolean getKeep() { return keep; } public void setKeep(boolean keep) { this.keep = keep; } public void calcXYWidthHeight(int x1, int y1, int x2, int y2) { int width = Math.abs(x2-x1); int height = Math.abs(y2-y1); // now I need to find my upper left corner point // find the x1 value if (x2 <= x1) { x1 = x2; } // find the y1 value if (y2 <= y1) // they have dragged the mouse up { y1 = y2; } // now set the instance variables of the class setX(x1); setY(y1); setWidth(width); setHeight(height); } } class Line extends AbstractShapeObject { int x2; int y2; public Line(int x1, int y1, int x2, int y2) { super(x1,y1); this.x2 = x2; this.y2 = y2; } public Line(int x1, int y1, int x2, int y2, Color color) { super(x1,y1,0,0,color); this.x2 = x2; this.y2 = y2; } public Line(int x1, int y1, int x2, int y2, int thickness) { super(x1,y1,0,0,thickness); this.x2 = x2; this.y2 = y2; } public Line(int x1, int y1, int x2, int y2, int thickness, Color color) { super(x1,y1,0,0,thickness,color); this.x2 = x2; this.y2 = y2; } public int getX1() { return getX(); } public void setX1(int x) { setX(x); } public int getY1() { return getY(); } public void setY1(int y) { setY(y); } public int getX2() { return x2; } public void setX2(int x2) { this.x2 = x2; } public int getY2() { return y2; } public void setY2(int y2) { this.y2 = y2; } public void draw(Graphics window) { // first, set your draw color window.setColor(getColor()); // second, draw the shape window.drawLine(getX(),getY(),getX2(),getY2()); } // each toString() method must use this format public String toString() { return getMode() + "," + getX1() + "," + getY1() + "," + getX2() + "," + getY2() + "," + getColor().getRed() + "," + getColor().getGreen() + "," + getColor().getBlue(); } } class Rectangle extends AbstractShapeObject { public Rectangle() { super(); } public Rectangle(int x, int y, int width, int height) { super(x,y,width,height); } public Rectangle(int x, int y, int width, int height, Color color) { super(x,y,width,height,color); } public Rectangle(int x, int y, int width, int height, int thickness) { super(x,y,width,height,thickness); } public Rectangle(int x, int y, int width, int height, int thickness, Color color) { super(x,y,width,height,thickness,color); } public void draw(Graphics window) { // first, set your draw color window.setColor(getColor()); // second, draw the shape window.drawRect(getX(),getY(),getWidth(),getHeight()); } // each toString() method must use this format public String toString() { return getMode() + "," + getX() + "," + getY() + "," + getWidth() + "," + getHeight() + "," + getColor().getRed() + "," + getColor().getGreen() + "," + getColor().getBlue(); } } Define other Shape objects