Lecture 19

advertisement
Lecture 19
Topics: Abstract Classes and Interfaces
Abstract Classes
Interfaces
o The Comparable interface
o The Cloneable Interface - optional
Readings:
Lecture Notes
Chapter 15
A superclass defines common behavior for related subclasses. In the inheritance
hierarchy, classes become more and more specific and concrete with each new subclass.
An interface can be used to define common behavior for classes including unrelated
classes.
Abstract classes are very general. They cannot be used to create (instantiate) objects.
An abstract class can contain abstract methods. These methods are implemented in
subclasses.
public abstract class person {
}
Let’s take a look at the following example: GeometricObject.java
public abstract class GeometricObject {
private String color = "white";
private boolean filled;
private java.util.Date dateCreated;
/** Construct a default geometric object */
/** Defined as protected; can only be used by subclasses */
protected GeometricObject() {
dateCreated = new java.util.Date();
}
/** Construct a geometric object with color and filled value */
protected GeometricObject(String color, boolean filled) {
dateCreated = new java.util.Date();
this.color = color;
this.filled = filled;
}
1|Page
//getters and setters
/** Return color */
public String getColor() {
return color;
}
/** Set a new color */
public void setColor(String color) {
this.color = color;
}
/** Return filled. Since filled is boolean,
* the get method is named isFilled */
public boolean isFilled() {
return filled;
}
/** Set a new filled */
public void setFilled(boolean filled) {
this.filled = filled;
}
/** Get dateCreated */
public java.util.Date getDateCreated() {
return dateCreated;
}
/** Return a string representation of this object */
public String toString() {
return "created on " + dateCreated + "\ncolor: " + color +
" and filled: " + filled;
}
/** Abstract method getArea */
public abstract double getArea();
/** Abstract method getPerimeter */
public abstract double getPerimeter();
}
The methods getArea() and getPerimeter() defined in the GeometricObject are
overridden in the Circle class and the Rectangle class.
2|Page
public class TestGeometricObject {
/** Main method */
public static void main(String[] args) {
// Declare and initialize two geometric objects
GeometricObject geoObject1 = new Circle(5);
GeometricObject geoObject2 = new Rectangle(5, 3);
System.out.println("The two objects have the same area? " +
equalArea(geoObject1, geoObject2));
// Display circle
displayGeometricObject(geoObject1);
// Display rectangle
displayGeometricObject(geoObject2);
} //end main
/** A method for comparing the areas of two geometric objects */
public static boolean equalArea(GeometricObject object1,
GeometricObject object2) {
return object1.getArea() == object2.getArea();
}
/** A method for displaying a geometric object */
public static void displayGeometricObject(GeometricObject object) {
System.out.println();
System.out.println("The area is " + object.getArea());
System.out.println("The perimeter is " + object.getPerimeter());
}
}
When invoking equalArea(geoObject1, geoObject2) the getArea() method
defined in the Circle class is used for object1.getArea() and the getArea()
method defined in the Rectangle class is used for object2.getArea(). This is
possible due to the fact that getArea() is declared as abstract method.
In UML graphic notation the abstract methods are italicized.
Abstract classes:
o An Abstract class helps defining a base case for a specific set of objects.
o Cannot be contained in a non-abstract class. A class that contains abstract
methods must be abstract. Abstract methods can only be contained in abstract
classes.
o Cannot be used to create objects but it can have its own constructors invoked in
the constructors of its subclasses.
o Can contain a mix of concrete (implemented) methods and abstract
(unimplemented) methods. An abstract class can contain no abstract methods.
3|Page
o In order to create an instance of an Abstract class you must first extend it from a
concrete (non abstract) class.
This can be done by overriding the abstract method in the concrete class.
o Extending an Abstract class from a concrete class forces the subclass to
implement all abstract methods.
o If a subclass extends an abstract class and does not implement all the abstract
methods then it must be declared as abstract.
o An abstract class can be used as a data type. Therefore the following is correct:
GeometricObject[] objects = new GeometricObject[10];
You can then create an instance of GeometricObject and assign its
reference to the array:
objects[0] = new Circle;
Choosing interfaces and abstract classes is not an either/or proposition. If you need to change
your design, make it an interface. However, you may have abstract classes that provide some
default behavior. Abstract classes are excellent candidates inside of application frameworks.
Abstract classes let you define some behaviors; they force your subclasses to provide others. For
example, if you have an application framework, an abstract class may provide default services
such as event and message handling. Those services allow your application to plug in to your
application framework. However, there is some application-specific functionality that only your
application can perform. Such functionality might include startup and shutdown tasks, which
are often application-dependent. So instead of trying to define that behavior itself, the abstract
base class can declare abstract shutdown and startup methods. The base class knows that it
needs those methods, but an abstract class lets your class admit that it doesn't know how to
perform those actions; it only knows that it must initiate the actions. When it is time to start up,
the abstract class can call the startup method. When the base class calls this method, Java calls
the method defined by the subclass class.
Case Study: the Abstract Number Class pp 565
We discussed wrappers a while ago. Number is an abstract superclass for numeric
wrapper classes like BigInteger, BigDecimal and so on.
intValue, longValue, floatValue and doubleValue cannot be implemented in the Number
class since they are specific to the type of data. They are defined as abstract methods in
the Number abstract class.
4|Page
Interfaces
The Java interface is used to share common behavior (only method headers) among
the instances of different classes.
Inheritance is used to share common code (including both data members and
methods) among the instances of related classes.
An interface is a class-like construct that contains only constants and abstract methods.
An interface is used to specify common behavior for objects of (related or unrelated)
classes.
modifier interface InterfaceName{
//constant declarations
//abstract method signature
}
Example:
Teacher
Person (abstract)
name: String
speak(): void
sleep(): void
eat():void
Student
Animal (abstract)
name: String
eat():void
sleep():void
play():void
Jaguar
Pig
Pre-K
Which of these classes is very messy? Let’s say one good answer might be Pre-K and
Pig. Pre-K and Pig are in different abstract (unrelated) classes. How can we connect
them through this common characteristic?
Let’s say we have a special method named cleanAfterMe(). We do not want to have
this method implemented at the level of Teacher or Jaguar, not even the Student.
It can be done by creating an interface.
5|Page
Person (abstract)
name: String
speak(): void
sleep(): void
eat():void
Teacher
Student
Animal (abstract)
name: String
eat():void
sleep():void
play():void
Jaguar
Pig
Pre-K
Messy Interface
cleanAfterMe():void
public interface Messy{
//contains abstract methods and/or constants only
public abstract void cleanAfterMe();
}
We also must mention that the class will implement that interface:
public class Pre-K extends Person implements Messy {
…..
}
public class Pig extends Animal implements Messy{
……………
}
6|Page
Classes that implement an interface MUST implement all its methods in order to
compile.
If a superclass implements an interface, then its subclasses must implement the same
interface.
Interfaces can be used as a data type, allowing you to store in a common collection
unrelated objects.
Messy[] messyCreatures = new Messy[2];
messyCreatures[0] = new Pre-K(“nana”);
messyCreatures[1] = new Pig(“peppa”);
Case Study: TestEdible.java pp 570
public interface Edible {
/** Describe how to eat */
public abstract String howToEat();
}
public class TestEdible {
public static void main(String[] args) {
Object[] objects = {new Tiger(), new Chicken(), new Apple()};
for (int i = 0; i < objects.length; i++) {
if (objects[i] instanceof Edible)
System.out.println(((Edible)objects[i]).howToEat());
if (objects[i] instanceof Animal) {
System.out.println(((Animal)objects[i]).sound());
}
}
}
}
abstract class Animal {
/** Return animal sound */
public abstract String sound();
}
class Chicken extends Animal implements Edible {
@Override
public String howToEat() {
return "Chicken: Fry it";
}
@Override
7|Page
public String sound() {
return "Chicken: cock-a-doodle-doo";
}
}
class Tiger extends Animal {
@Override
public String sound() {
return "Tiger: RROOAARR";
}
}
abstract class Fruit implements Edible {
// Data fields, constructors, and methods omitted here
}
class Apple extends Fruit {
@Override
public String howToEat() {
return "Apple: Make apple cider";
}
}
class Orange extends Fruit {
@Override
public String howToEat() {
return "Orange: Make orange juice";
}
}
The Comparable interface
The comparable interface defines the compareTo() method for comparing objects.
//interface for comparing objects
package java.lang;
public interface Comparable<E>{
public int compareTo(E o);
}
compareTo(): accepts a reference to another object and returns an integer.
Returns +1 if the object is bigger than the one is being compared to.
Returns 0 if the objects are the same.
Returns -1 if the object is smaller than the one is being compared to.
8|Page
public class SpongeBob implements Comparable<SpongeBob>{
}
public class String extends Object implements Comparable<String>{
}
@Override
public int compareTo(String o){
}
Numbers, Strings and dates are comparable. Not everything is comparable.
Let’s say you want to compare hundreds of objects and not just two. The solution is by
using the Comparable interface. If you implement the Comparable interface you can
use Java’s sort built-in functionality.
You cannot use java.util.Arrays.sort() to sort an array of Rectangles objects,
because Rectangle does not implement Comparable.
public class ComparableRectangle extends Rectangle
implements Comparable<ComparableRectangle> {
/** Construct a ComparableRectangle with specified properties */
public ComparableRectangle(double width, double height) {
super(width, height);
}
@Override // Implement the compareTo method defined in Comparable
public int compareTo(ComparableRectangle o) {
if (getArea() > o.getArea())
return 1;
else if (getArea() < o.getArea())
return -1;
else
return 0;
}
@Override // Implement the toString method in GeometricObject
public String toString() {
return "Width: " + getWidth() + " Height: " + getHeight() +
" Area: " + getArea();
}
}
9|Page
ComparableRectangle extends Rectangle and implements Comparable
(inherits all the constants from Comparable interface and implements the methods in
the interface). compareTo method compare the area of the two rectangles.
An instance of ComparableRectangle is an instance of Rectangle, GeometricObject,
Object and Comparable.
public class SortRectangles {
public static void main(String[] args) {
ComparableRectangle[] rectangles = {
new ComparableRectangle(3.4, 5.4),
new ComparableRectangle(13.24, 55.4),
new ComparableRectangle(7.4, 35.4),
new ComparableRectangle(1.4, 25.4)};
java.util.Arrays.sort(rectangles);
for (Rectangle rectangle: rectangles) {
System.out.print(rectangle + " ");
System.out.println();
}
}
}
Interfaces vs. Abstract Classes
A class can implement multiple interfaces, but it can only extend one superclass.
Java allows only single inheritance for class extension but allows multiple extensions for
interfaces.
Table 15.2
Variables
Constructors
Methods
Abstract Class
No restrictions.
No restrictions.
Interface
All variables must be
Are invoked by
subclasses.
No constructors. An
interface cannot be
instantiated using
the new operator
public static final
All must be
public abstract
instance methods.
10 | P a g e
The Cloneable Interface specifies that an object can be cloned.
package java.lang;
public interface Cloneable{
}
The objects can be cloned using the clone() method defined in the Object class.
Many classes in the Java library implement Cloneable.
You can clone an array using the clone method:
int[] list1 = {1,2};
int [] list2 = list1.clone();
list1[0]=7;
list2[1]=8;
list1
list 2
1,2
1,2
list1
list2
7,2
1,8
List 1 is 7,2
List 2 is 1,8
How to implement Cloneable
The class must override the clone() method in the Object class.
Case study: House.java implements Cloneable and Comparable.
public class House implements Cloneable, Comparable <House> {
private int id;
private double area;
private java.util.Date whenBuilt;
public House(int id, double area) {
this.id = id;
this.area = area;
whenBuilt = new java.util.Date();
}
public double getId() {
return id;
}
public double getArea() {
return area;
11 | P a g e
}
public java.util.Date getWhenBuilt() {
return whenBuilt;
}
/** Override the protected clone method defined in the Object
class, and strengthen its accessibility */
@override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/** Implement the compareTo method defined in Comparable */
@override
public int compareTo(Object o) {
if (area > ((House)o).area)
return 1;
else if (area < ((House)o).area)
return -1;
else
return 0;
}
}
You can create an object of the House class and create an identical copy from it:
House house1 = new House(1 , 1750);
House house2 = (House) house1.clone();
The clone method copies each field from the original object to the target object. If the
field is of primitive type its value is copied. If the field is of an object, the reference of
the field is copied. The object’s reference type is copied rather than its content: shallow
copy.
NOTE: An interface can extend other interfaces but not classes. A class can extend its
superclass and implement multiple interfaces.
12 | P a g e
Download