Polymorphism in Java

A polymorphic reference is a variable that can refer to different types of objects. A reference can refer to an object of its class, or to an object of any subclass.

Mammal m = new Mammal(); 
Horse h = new Horse(); 
m = h; 		// good 
h = m; 		// bad

When we call a method through a polymorphic reference, the method is determined by the type of the object being referenced (not the reference type). The method to be called may change as the referred object changes.

A Java interface is a collection of abstract methods and constants. An abstract method is just a method header without a method body. All methods in an interface are abstract. Methods in interfaces are implicitly abstract, public. Constants are implicitly final, static, public. These modifiers are often omitted.

A class implements an interface by defining each method in the interface. An interface cannot be instantiated. An interface can be used to derive another interface. An interface cannot be used to derive a class, and a class cannot be used to derive an interface.
Class extends one class
Class implements many interfaces
Interface extends many interfaces

Interfaces vs. abstract classes. Neither of them can be instantiated. They are both used to build reusable codes. The difference is that, an abstract class may contain non-abstract methods and non-constant attributes; an interface contains only abstract methods and constants.

We can define a class or an interface managing objects of unknown type. The type will be specified when creating objects.

class Box<T> 		// T in angle brackets 
{ // manage objects of type T } 
Box<Widget> b1 = new Box<Widget>; 
Box<Gadget> b2 = new Box<Gadget>;

Examples of interfaces:

public interface Comparable
This interface imposes a total ordering on the objects of each class that implements it
int compareTo(T o)
Compares this object with the specified object for order. Returns a negative integer (less than), zero (equal to), or a positive integer (greater than)
The String class implements Comparable.
“alice”.compareTo(“bob”);

public interface Iterator
Provides a way to loop over a collection of objects
boolean hasNext()
E next()
The Scanner class implements Iterator

Scanner sc = new Scanner(...); 
while (sc.hasNext()) 
String str = sc.next();

The following example defines an abstract class Shape, with subclasses Circle and Rectangle. The class Circle also implements the interface Comparable.

public abstract class Shape 
{
	protected int x;
	protected int y;
		
	public Shape(int _x, int _y) { x = _x; y = _y; }
	public void setX(int _x) { x = _x; } 
	public void setY(int _y) { y = _y; } 
	public int getX() { return x; } 
	public int getY() { return y; } 
		
	public abstract void draw();
	public abstract double area();
	public abstract double perimeter(); 
}

public class Circle extends Shape implements Comparable<Circle>
{
	private int r;
	public Circle(int _x, int _y, int _r)
	{
		super(_x, _y); 
		r = _r;
	}
		
	public void setRadius(int _r) { r = _r; }
	public int getRadius() { return r; } 

	public int compareTo(Circle b)
	{
		return r - b.r;
	} 
		
	public void draw()
	{
		System.out.println("Draw a circle of radius " + r 
			+ " at (" + x + ", " + y +")");
	}
	public double area()
	{
		return r * r * Math.PI;
	}
	public double perimeter()
	{
		return 2 * r * Math.PI;
	}

}

public class Rectangle extends Shape
{
	private int l;
	private int w;

	public Rectangle(int _x, int _y, int _l, int _w)
	{
		super(_x, _y); 
		l = _l;
		w = _w;
	}

	public void setLength(int _l) { l = _l; } 
	public int getLength() { return l; } 
	public void setWidth(int _w) { w = _w; }
	public int getWidth() { return w; } 

	public void draw()
	{
		System.out.println("Draw a rectangle of length " + l + 
			" and width " + w + " at (" + x + ", " + y +")");
	}

	public double area()
	{
		return l * w;
	}

	public double perimeter()
	{
		return 2 * (l + w);
	}
}

Comments

comments