Abstract Classes and Polymorphism

advertisement
Interfaces,
Abstract Classes,
and Polymorphism
What Is an Interface?
• An interface is the set of public methods in
a class
• Java provides the syntax for specifying
interfaces independently of their
implementing classes
Example: An Interface for Circle
import java.awt.Graphics;
public interface CircleInterface {
public
public
public
public
void draw(Graphics g);
void move(int xDistance, int yDistance);
boolean equals(Object other);
String toString();
}
An interface contains public method signatures and any
necessary imports
Implementing an Interface
import java.awt.*;
public class Circle implements CircleInterface {
// Variables and methods
}
Circle must implement draw, move, equals, and toString
import java.awt.*;
public class Wheel extends Circle {
// Variables and methods
}
The Client’s Perspective
Circle c1 = new Circle(10,10,100,100,Color.blue);
CircleInterface c2 = new Circle();
CircleInterface[] list = new CircleInterface[25];
Clients just look at the interface to see what they can do
with circles
An interface name can be substituted for the name of
any implementing class
Implementing Several Interfaces
import java.awt.*;
import java.io.Serializable;
public class Circle implements CircleInterface,
Cloneable,
Comparable,
Serializable {
// Variables and methods
}
Circle must implement draw, move, equals, and toString
Circle must also implement clone and compareTo
Abstract and Concrete Classes
• An abstract class defines data and methods
common to all subclasses, but is never
instantiated
• A concrete class inherits some data and
methods, defines others, and is instantiated
Example: Other Shapes
Rectangles and triangles are not really special types of
circles, but have similar attributes and behavior
Rectangle
Circle
Wheel
Triangle
Define an AbstractShape Class
AbstractShape is
never instantiated, but
AbstractShape
simply holds data and
methods for its subclasses
Rectangle
Circle
Wheel
Each shape has a
position, size, and
color
Triangle
Most shapes move
in a similar manner
An Interface for All Shapes
import java.awt.Graphics;
public interface Shape {
public
public
public
public
}
void draw(Graphics g);
void move(int xDistance, int yDistance);
boolean equals(Object other);
String toString();
Defining an Abstract Class
abstract public class AbstractShape implements Shape{
protected Color color;
protected int x, y, width, height;
// Methods go here
}
import java.awt.*;
public class Circle extends AbstractShape {
// Methods go here
}
abstract means that the class is not instantiated
Polymorphism
• The move, draw, toString, and
equals methods are polymorphic, in that
they’re included in all classes but are
implemented differently in some of them
• Try to exploit polymorphism to
– reduce the amount of redundant code
– reduce the conceptual overhead for clients
Abstract Methods
// In the AbstractShape class
abstract public void draw(Graphics g);
The keyword abstract requires all subclasses
to implement a method
An abstract method is implemented differently in each
subclass
When a Method Can’t Be Supported
// In the AbstractShape class
abstract public double getArea();
// In the Rectangle class
public double getArea(){
return width * height;
}
// In the Line class
public double getArea(){
throw new UnsupportedOperationException("Lines have no area");
return 0;
}
Overriding a Method
// In the AbstractShape class
public void move(int xDistance, int yDistance)
x += xDistance;
y += yDistance;
}
// In the Triangle class
public void move(int xDistance, int yDistance)
super.move(xDistance, yDistance);
// Code to adjust the other vertices goes here
}
Final Methods
// In the AbstractShape class
public final void setColor(Color c){
color = c;
}
The keyword final prohibits any subclass
from overriding a method.
Types of Polymorphism
• Behavioral – several classes implement one
interface
• Structural – several classes implement one
abstract class
The Advantages of Polymorphism
// Create an array to hold up to 3 shapes of any type
Shape[] shapes = new Shape[3];
// Add several shapes to the array
shapes[0] = new Circle(50,50,100,100, Color.red);
shapes[1] = new Rectangle(0,0,50,50, Color.blue);
shapes[2] = new Triangle(0,0,100,100,60,30, Color.red);
// Move them and draw them all
for (int i = 0; i < shapes.length; i++){
shapes[i].move(50, 50);
shapes[i].draw(g);
}
Watch Out for Type Mismatches
// Set the number of spokes of all wheels to 6
for (int i = 0; i < shapes.length; i++)
shapes[i].setSpokes(6);
Causes a compile-time error, because setSpokes is
not included in the Shape interface and the array’s
element type is Shape
Casting to the Rescue
// Set the number of spokes of all wheels to 6
for (int i = 0; i < shapes.length; i++){
Wheel w = (Wheel)shapes[i];
w.setSpokes(6);
}
The compiler is now happy, but if shapes[i] is not
actually a Wheel at run time, a ClassCastException
will be thrown
Ask First
// Set the number of spokes of all wheels to 6
for (int i = 0; i < shapes.length; i++){
if (shapes[i] instanceof Wheel){
Wheel w = (Wheel)shapes[i];
w.setSpokes(6);
}
}
Now both the compiler and the JVM will be happy
For Friday
• Exceptions and error handling
• Serialization (file transfers)
Download