Polymorphism and Interfaces
Savitch 8.3-8.4
Topics
8.3 – Polymorphism
Polymorphism
- A method is polymorphic if it can be called on different types of objects or with different parameters types.
- Method overloading is a form of polymorphism where methods with different parameter types share the same name.
- Inheritance makes base class methods polymorphic since they can be called on objects of a derived class.
- Overriding inherited methods makes them behave differently when they are called on an object of a derived class.
- Polymorphism also allows changes in a derived class method to apply to corresponding base class method.
Compile-Time and Run-Time Types
- The compile-time type of a variable of class type is determined by the variable declaration:
1
2
|
Person person1; // compile-time type is Person
Person person2; // same
|
- The run-time type of a variable of class type is determined when the variable is assigned a value:
1
2
|
person1 = new Person("Strachey, Christopher"); // run-time type is Person
person2 = new Student("Liskov, Barbara", 1171939); // run-time type is Student
|
Dynamic Binding and Inheritance
- Java uses dynamic binding, so the run-time type determines which implementation of a method is used when it called.
- Code:
1
2
3
|
person1.writeOutput(); // calls Person implementation
System.out.println();
person2.writeOutput(); // calls Student implementation
|
Name: Strachey, Christopher
Name: Liskov, Barbara
Student Number: 1171939
Dynamic Binding with toString
- If a
toString
method is implemented in a class, an object of that class can be passed to System.out.println
.
1
2
|
Student student = new Student("Church, Alonso", 6141903);
System.out.println(student);
|
- This words because
System.out.println
calls the toString
method on the Object
passed a parameter.
1
2
3
|
public void println(Object object) {
println(object.toString()); // calls the version that takes a String
}
|
- If the
Student
class overrides the Object
class implementation of toString
, then the Student
class implementation will be called.
8.4 – Interfaces and Abstract Classes
Java Interfaces
- A Java interface is a program component that contains the heading for a number of public methods.
- An interface can be declared using the keyword interface.
1
|
public interface Interface_Name
|
- The interface contains headers for public methods, each followed by a semicolon.
1
2
3
4
5
|
public interface Measurable
{
public double getPerimeter();
public double getArea();
}
|
Implementing an Interface
- A class can implement an interface by doing the following:
- Includes
implements Interface_Name
in the class definition header.
- Define every method declared in the interface.
- If multiple interfaces are implemented, the interface names can be separated by commas.
- For example, the class definition header for a
Rectangle
class that implements the Measurable
interface would look like this:
1
|
public class Rectangle implements Measurable
|
- The
Rectangle
class would need to implement the getPerimiter
and getArea
methods as specified in the Measurable
Interface.
The Rectangle
Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Rectangle implements Measurable {
private double myWidth;
private double myHeight;
public Rectangle(double width, double height) {
myWidth = width;
myHeight = height;
}
public double getPerimeter() {
return 2 * (myWidth + myHeight);
}
public double getArea() {
return myWidth * myHeight;
}
}
|
An Interface as a Type
- An interface is a reference type, so it can used as the type of a variable or parameter.
1
2
3
4
|
public static void display(Measurable figure) {
System.out.println("Perimeter = " + figure.getPerimeter());
System.out.println("Area = " + figure.getArea());
}
|
- A variable with an interface type can be assigned an object of any class that implements the interface.
1
2
3
4
|
Measurable box = new Rectangle(5.0, 5.0);
Measurable disc = new Circle(5.0);
display(box); // calls Rectangle implementations of getPerimeter and getArea
display(disc); // calls Circle implementations of getPerimeter and getArea
|
The Circle
Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class Circle implements Measurable {
private double myRadius;
public Circle(double radius) {
myRadius = radius;
}
public double Perimeter() {
return 2 * Math.PI * myRadius;
}
public double getCircumference() { // alternate name for getPerimeter
return getPerimeter();
}
public double getArea() {
return Math.PI * myRadius * myRadius;
}
}
|
Extending an Interface
- An interface can extend one or more existing interfaces:
1
2
3
4
5
6
7
8
|
public interface Nameable {
public void setName(String petName);
public String getName();
}
public interface Callable extends Nameable {
public void come(String petName)
}
|
- A class that implements
Callable
must implement the two methods in Nameable
as well as the one in Callable
.
Case Study: Character Graphics
- Problem: design interfaces and classes to support a program that draws shapes using text characters.
- The program will use the following interfaces:
-
ShapeInterface
: draw a shape and configure where it should be drawn.
-
RectangleInterface
: set the height and width of a rectangle.
-
TriangleInterface
: set the base length of the triangle.
- The program will use the following classes:
-
ShapeBasics
: a base class that implements ShapeInterface
-
Rectangle
: a derived class that implements RectangleInterface
-
Triangle
: a derived class that implements TriangleInterface
Character Graphics Interfaces
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public interface ShapeInterface {
public void setOffset(int newOffset); // sets horizontal offset
public int getOffset();
public void drawAt(int lineNumber); // draws after lineNumber blank lines
public void drawHere();
}
public interface RectangleInterface extends ShapeInterface {
public void set(int newHeight, int newWidth); // adjusts the height and width
}
public interface TriangleInterface extends ShapeInterface {
public void set(int newBase); // adjusts the base length
}
|
The ShapeBasics
Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class ShapeBasics implements ShapeInterface {
private int offset;
public ShapeBasics() {
offset = 0;
}
public ShapeBasics(int theOffset) {
offset = theOffset;
}
public void setOffset(int newOffset) {
offset = newOffset;
}
public void getOffset() {
return offset;
}
public void drawAt(int lineNumber) {
for (int count = 0; count < lineNumber; count++)
System.out.println();
drawHere();
}
public void drawHere() {
for (int count = 0; count < offset; count++ )
System.out.print(' ');
System.out.println('*');
}
}
|
The Rectangle
Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class Rectangle extends ShapeBasics implements RectangleInterface {
private int height;
private int width;
public Rectangle() {
super();
height = 0;
width = 0;
}
public Rectangle(int theOffset, int theHeight, int theWidth) {
super(theOffset);
height = theHeight;
width = theWidth;
}
// implements set from RectangleInterface
public void set(int newHeight, int newWidth) {
height = newHeight;
width = newWidth;
}
// overrides drawHere from ShapeBasics
public void drawHere() {
drawHorizontalLine();
drawSides();
drawHorizontalLine();
}
// private methods to implement drawHere
}
|
The Triangle
Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class Triangle extends ShapeBasics implements TriangleInterface {
private int base;
public Triangle() {
super();
base = 0;
}
public Triangle(int theOffset, int theBase) {
super(theOffset);
base = theBase;
}
// implements set from TriangleInterface
public void set(int newBase) {
height = newHeight;
width = newWidth;
}
// overrides drawHere from ShapeBasics
public void drawHere() {
drawTop();
drawBase();
}
// private methods to implement drawHere
}
|
Case Study: The Comparable Interface
- Java has a predefined interface called
Comparable
that contains header for a compareTo
method.
1
|
public int compareTo(Object other);
|
- An implementation of
compareTo
should return:
- A negative number if the calling object comes before
other
- A zero if the calling object equals
other
- A positive number if the calling object comes after
other
- An array of objects that implement the
Comparable
interface can be passed to Array.sort
, which uses compareTo
for comparisons.
Defining compareTo
- The
compareTo
method should handle the following cases:
- The parameter is the same type or derived from the type of the calling object.
- The parameter is not the same type or derived from the type of the calling object.
- The parameter is
null.
- A
compareTo
method for the Person class might look like this:
1
2
3
4
5
6
7
|
public int compareTo(Object object) {
if(object != null && object instanceof Person) {
Person otherPerson = (Person)object;
return name.compareTo(otherPerson.name);
}
return -1;
}
|
Abstract Classes
- The
ShapeBasics
class was designed as a base class for other classes, not for creating objects of its own.
- It could be reimplemented as an abstract class, which can not be instantiated and contains abstract methods that must be overridden.
1
2
3
4
5
6
7
8
9
10
|
public abstract class ShapeBase implements ShapeInterface {
private int offset;
public abstract void drawHere(); // must be overridden;
public void drawAt(int linenumber) {
for(int count = 0; count < lineNumber; count++)
System.out.println();
drawHere(); // calls derived class method
}
// other methods
}
|
Powerpoint
Quiz
Quiz 4