Transcript Chap6
Problem Solving
with Java™
Second Edition
Elliot Koffman and
Ursula Wolz
Prepared by: Elliot Koffman, Temple University and Dorina Petriu, Carleton University
Copyright
Copyright©©2003
2003Pearson
PearsonEducation,
Education,Inc.
Inc.
Slide 6-1
Chapter 6
Class Hierarchies, Inheritance, and
Interfaces
Copyright © 2003 Pearson Education, Inc.
Slide 6-2
Chapter Objectives
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
Class Hierarchies and Inheritance
Case Study: A Hierarchy of Employee Classes
Operations in a Class Hierarchy
Polymorphism
Case Study: A Company with an Array of Employees
of Different Types
Interfaces
Abstract Classes
Case Study: Areas of Geometric Figures
Drawing Figures using an Abstract Class and an
Interface
Case Study: Drawing Geometric Figures
Packages and Visibility (Optional)
Testing Program Systems
Copyright © 2003 Pearson Education, Inc.
Slide 6-3
6.1 Class Hierarchies and Inheritance
Object-oriented programming languages enable programmers to take
advantage of code reuse in multiple ways.
• Language developers provide packages (libraries of classes).
• Programmers create their own packages, all of which can be reused for
writing new applications.
• New classes can be developed as extensions of earlier classes through
inheritance.
INHERITANCE facilitates class reuse: You can create a new class from an
existing class, by extending the existing class, rather than rewriting it.
• The new class (called the subclass) can have additional data fields and
methods for increased functionality.
• Its objects also inherit the data fields and methods of the original class
(called the superclass).
Copyright © 2003 Pearson Education, Inc.
Slide 6-4
Example of inheritance
NewEmployee
HourlyEmployee
SalaryEmployee
is a general employee class. Stores information such
as name, social security number, phone number, address, etc.
NewEmployee
is a specialized class for employees who are paid
by the hour. An HourlyEmployee object stores hours and rate data.
HourlyEmployee
is a specialized class for employees who are paid a
monthly salary. A SalaryEmployee object stores annual salary data.
SalaryEmployee
Copyright © 2003 Pearson Education, Inc.
Slide 6-5
Class NewEmployee (w/o accessors and setters)
Data Fields
String name
String socSecNum
String jobTitle
String address
String phoneNumber
int age
int startYear
double totalPay
Attributes
•name
•social security number
•job title
•address
•phone number
•age
•starting year of employment
•total pay to date
Methods
int calcYearsService(int)
int calcYearsToRetire()
Behavior
•Computes years with company. The
current year is an argument.
•Computes years until retirement.
boolean
equals(NewEmployee)
double
updateTotalPay(double)
String toString()
•Determines whether this employee has
same social as employee argument.
•Increases total pay by the amount
specified (the argument).
•Represents object as a string.
Copyright © 2003 Pearson Education, Inc.
Slide 6-6
Classes SalaryEmployee and HourlyEmployee
SalaryEmployee class
HourlyEmployee class
Data Fields
Data Fields
salary
hours
rate
Methods
Methods
void setSalary(double)
double computeWeeklyPay()
double getSalary()
String toString()
void setHours(double)
void setRate(double)
double computeWeeklyPay()
double getHours()
double getRate()
String toString()
Besides the data fields and methods shown, each class inherits the data fields
and methods of superclass NewEmployee. This means an object of type
SalaryEmployee or HourlyEmployee also has the data and methods of the
superclass Employee.
Copyright © 2003 Pearson Education, Inc.
Slide 6-7
Class NewEmployee data fields & selected methods
public class NewEmployee {
// data fields
protected String name = "";
protected String socSecNum = "";
protected String jobTitle = "";
protected String address = "";
protected String phoneNumber = "";
protected int age;
protected int startYear;
protected double totalPay;
Protected data fields
may be accessed in
this class or in a subclass.
// methods
// constructors
public NewEmployee() {
}
public NewEmployee(String name, String social) {
this.name = name;
Stores argument name in
socSecNum = social;
}
data field name of this object.
public NewEmployee(String name, String social, String job,
String address, String phone,
int age, int year, double totPay) {
this(name, social);
jobTitle = job;
Calls 2-argument constructor
this.address = address;
phoneNumber = phone;
to initialize data fields.
this.age = age;
Must be first statement.
startYear = year;
totalPay = totPay;
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-8
Class NewEmployee, cont’d.
// precondition: the argument is the current year
// postcondition: Returns the number of years worked
public int calcYearsService(int year) {
return year - startYear;
}
// postcondition: Returns the number of years until employee
//
will reach the retirement age of 65. Returns 0 if employee
//
has reached retirement age.
public int calcYearsToRetire() {
int RETIREMENT_AGE = 65; // normal retirement age
int yearsToRetire = RETIREMENT_AGE - age;
if (yearsToRetire > 0)
return yearsToRetire;
else
return 0;
}
public void updateTotalPay(double pay) {
totalPay += pay;
}
// postcondition: Returns true if this object has the same
//
social security number as the argument.
public boolean equals(NewEmployee emp) {
return this.socSecNum.equals(emp.socSecNum);
}
// insert accessors, setters, and toString()
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-9
Class SalaryEmployee
public class SalaryEmployee extends NewEmployee {
// data fields
private double annualSalary;
// methods
// constructors
public SalaryEmployee() {
}
subclass of
NewEmployee
public SalaryEmployee(String name, String social) {
super(name, social);
}
public SalaryEmployee(String name, String social, String job,
String address, String phone, int age,
int year, double totPay, double salary) {
super(name, social, job, address, phone, age, year, totPay);
annualSalary = salary;
}
Superclass constructor
// insert accessors and setters
initializes ineritetd data fields.
Must be first statement.
public String toString() {
return super.toString() +
"\nannual salary $" + annualSalary;
}
}
Calls superclass
toString() method
Copyright © 2003 Pearson Education, Inc.
Slide 6-10
Class HourlyEmployee
public class HourlyEmployee extends NewEmployee {
// data fields
private double hours;
private double rate;
// methods
// constructors
public HourlyEmployee() {
}
subclass of
NewEmployee
public HourlyEmployee(String name, String social) {
super(name, social);
}
public HourlyEmployee(String name, String social, String job,
String address, String phone, int age, int year,
double totPay, double hours, double rate) {
super(name, social, job, address, phone, age, year, totPay);
this.hours = hours;
this.rate = rate;
}
Calls superclass constructor
public double calcWeeklyPay() {
to initialize inherited data fields.
return hours * rate;
}
Must be first statement.
public String toString() {
return super.toString() +
"\nweekly hours: " + hours +
", hourly rate $" + rate;
}
Calls superclass
}
toString() method
Copyright © 2003 Pearson Education, Inc.
Slide 6-11
Testing employee class hierarchy
public class TestEmployeeClasses {
public static void main(String[] args) {
HourlyEmployee clerk =
new HourlyEmployee("Sam", "1234", "clerk", "", "",
30, 2000, 15000.00, 40.0, 15.0);
SalaryEmployee supervisor =
new SalaryEmployee("Jessica", "2222", "supervisor", "", "",
33, 1998, 40000.00, 52000.00);
3 employees
NewEmployee spouseOfBoss = new NewEmployee("George", "3456");
double weekPay = clerk.calcWeeklyPay();
clerk.updateTotalPay(weekPay);
System.out.println(clerk.toString());
System.out.println(clerk.getName() + " " +
clerk.getSocial() +
", weekly salary $" + weekPay + "\n");
weekPay = supervisor.calcWeeklyPay();
supervisor.updateTotalPay(weekPay);
System.out.println(supervisor.toString());
System.out.println(supervisor.getName() + " " +
supervisor.getSocial() +
", weekly salary $" + weekPay + "\n");
spouseOfBoss.updateTotalPay(500.00);
System.out.println(spouseOfBoss.toString() + "\n");
if (!clerk.equals(supervisor))
System.out.println(clerk.getName() + " and " +
supervisor.getName() + " are different employees");
}
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-12
Testing employee class hierarchy, cont’d.
Copyright © 2003 Pearson Education, Inc.
Slide 6-13
6.2 Operations in a class Hierarchy
UML Class Diagram
UML Sequence Diagram
Identify
Mammal
getName()
student:
Human
new()
name: String
getName()
return
Human
getIq()
Identify
getIq()
main()
return
iQ: int
An object of the subclass Human contains both the variables
and methods defined in its class, and those defined in its
superclass Mammal.
A Human constructor may invoke its superclass constructor by
using the reserved word super (to initialize its variables). If
the superclass constructor is not called, its variable will be
initialized to default values.
Visibility modifiers public, private and protected determine
what is accessible where.
An object of class
Human
getName()
getIQ()
name: String
iQ: int
Copyright © 2003 Pearson Education, Inc.
Slide 6-14
Encapsulation and visibility
Encapsulation:
clustering the data and methods together in a class (object).
Encapsulation builds a wall around an object’s private data, hiding the
details of the object from its users (a process called information hiding).
Private visibility is for members of a class that should not be accessible by
name to anyone but the class itself (not even the classes that extends it).
However, private variables of the superclass are defined (i.e., exist) in the
subclasses, and can be accesed only through superclass methods.
Protected visibility is for members of a class that should be accessible by
name only in the class and its subclasses (trade-off between inheritance and
encapsulation).
Copyright © 2003 Pearson Education, Inc.
Slide 6-15
Method overloading
•
•
Method overloading: define more than one method with the same name but
different signatures in a class. The compiler will differentiate the methods by their
signatures.
– method signature: method name, return type and argument specification
(number of arguments, order and type, but not their names)
Overloading example: constructors with different argument lists
public class Rectangle {
private int width;
private int length;
//constructors
public Rectangle() {};
public Rectangle(int w, int l) {
width = w;
length = l;
}
public Rectangle(int side) {
this (side, side); // activate the second constructor
}
The keyword this refers to the current object. The form this.memberName
refers to a variable or method, and the form this (...) to a constructor.
Copyright © 2003 Pearson Education, Inc.
Slide 6-16
Method overriding
• Method overriding: when a subclass redefines (overrides) a method
inherited from the superclass. The class of the object used to invoke
the method will decide which definition of the method is going to be
executed.
• Polymorphism means “multiple forms”. Both method overloading and
method overriding are example of polymorphism in OO systems (i.e.,
multiple forms of the same operation).
• Example of method overriding:
Messages
Thought
new()
message()
insight:
Thought
new()
caution:
Advice
message()
Advice
message()
Messages
return
message()
main()
return
Copyright © 2003 Pearson Education, Inc.
Slide 6-17
Example of method overriding
class Thought {
public void message() { // superclass method definition
System.out.println (”Inheritance is a powerful concept.");
} // method message
} // class Thought
class Advice extends Thought {
public void message() {
// overrides superclass definition
System.out.println (”Don’t use inheritance as a replacement ” +
“for simpler class composition!!!”);
} // method message
} // class Advice
public class Messages {
// Application class
public static void main (String[ ] args) {
Thought insight = new Thought();
Advice caution = new Advice();
insight.message();
// executes Thought’s method
caution.message();
// executes Advice’s method
}
} // class Messages
Copyright © 2003 Pearson Education, Inc.
Slide 6-18
Shadowing variables
Shadowing variables: when a subclass is redefining variables that were
inherited from the superclass (a process similar to overriding methods). The
closest variable definition “shadows” or hides the others.
class Parent {
protected int age = 35;
// . . .
} // class Parent
class Child extends Parent {
protected int age = 14; // redefines age
public int getAge() { return age; }
public int getParentAge() { return super.age; }
} // class Child
Access
public class Shadow {
hidden data
public static void main (String[] args) {
Child darkness = new Child();
System.out.println(darkness.getAge());
System.out.println(darkness.getParentAge());
}
} // class Shadow
Copyright © 2003 Pearson Education, Inc.
An object of class
Child
darkness: Child
getAge()
...
Parent.age
Child.age
Slide 6-19
Assignment and casting in a class hierarchy
• Type compatibility for reference variables and objects:
In Java,a reference variable can refer to an object created from a class
that is related to the reference variable type by inheritance.
// Horse is a subclass of Mammal
Mammal m = new Mammal();
Horse h = new Horse();
effect of: m
m = h; h
(no cast required assign up hierarchy)
a mammal
object
a horse
object
m
h
effect of:
a mammal
object
a horse
object
m
h = (Horse) m;
h
(explicit cast required assign down hierarchy)
a mammal
object
a horse
object
• Polymorphic references to overridden methods:
a reference of the form objectRef.methodName() to an overridden method
uses the type of the object, not the type of the reference variable, to
determine which version of the overridden method to invoke.
Example: each Mammal and Horse classes define its own method move().
m.move(); // execute Horse’s method
m.move(); // execute Mammal’s method
Copyright © 2003 Pearson Education, Inc.
Slide 6-20
The Object class
• In Java all classes are derived, directly or indirectly, from the Object class. If
a class definition does not use the extends clause, then that class is derived
from Object by default.
• Some useful Object methods (inherited and probably overridden by others):
– toString(): returns a string that represent the object. Used by the concatenation
operator of the String class to convert an object to a string (useful for display).
– equals (Object obj): returns true if this object and obj are the same.
public class Rectangle {
private int width, length;
...
// override toString() method inherited from Object
public String toString() {
return “length is ” + length + “, width is “ + width;
}
...
public static void main (String[ ] args) {
Rectangle r1 = new Rectangle(5, 10);
Rectangle r2 = new Rectangle(8, 15);
System.out.println (“r1: “ + r1+ “\nr2: “ + r2); } // end main
Output r1: length is 5, width is 10
Window r2: length is 8, width is 15
Copyright © 2003 Pearson Education, Inc.
automatically calls
method toString()
Slide 6-21
Method equals() for class NewEmployee
If emp is type NewEmployee, both method calls
emp.equals(emp) and emp.equals(“Joe”) will use the Object
class toString() method (with signature equals(Object)). In each
case, the argument (emp or “Joe”) is a subclass of Object.
Below we define an equals(Object) method for class
NewEmployee which overrides the one in class Object.
public boolean equals(Object emp) {
if (emp instanceof NewEmployee) {
NewEmployee tempEmp = (NewEmployee) emp;
return this.socSecNum.equals(tempEmp.socSecNum);
}
else {
true if employees
return false;
have same social
}
security #’s
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-22
6.3 Polymorphism and late binding
import java.util.*;
vector v elements
reference objects
of 3 types.
public class ShowPolymorphism {
public static void main(String[] args) {
Vector v = new Vector();
v.addElement("Jane");
// first element is a string
v.addElement(new Double(15.0)); // second element is type Double
v.addElement(new Double(45.5)); // third element is type Double
v.addElement(new Integer(100)); // fourth element is type Integer
toString() method
double sum = 0.0;
called is determined
for (int i = 0; i < v.size(); i++) {
at runtime.
Object temp = v.elementAt(i);
System.out.println(temp.toString());
true if temp
if (temp instanceof Double)
references a type
sum + = ((Double) temp).doubleValue();
Double object
}
System.out.println("Sum of double values in vector v is " + sum);
}
}
Copyright © 2003 Pearson Education, Inc.
sum is 60.5
Slide 6-23
6.4 Interfaces
An interface is used to specify a set of requirements that is
imposed on a collection of classes.
Classes that implement an interface are guaranteed to have
certain functionality (behavior) and also inherit any constants
that are defined in the interface.
We define an interface Payable. Classes that implement the
Payable interface are guaranteed to know how to calculate
weekly pay.
/* Payable.java
Authors: Koffman & Wolz
* The Payable interface.
*/
Abstract method that
public interface Payable {
must be defined in any
public double calcWeeklyPay();
class that implements
}
interface Payable.
Copyright © 2003 Pearson Education, Inc.
Slide 6-24
Syntax of interface definition
Form: public interface interfaceName {
abstract method headings
constant declarations
}
Example: public interface Payable {
public double calcWeeklyPay();
public static final double
DEDUCT_PCT = 5.5;
}
Interpretation: Interface interfaceName is defined. The interface
body provides headings for abstract methods and constant
declarations. Interfaces may extend other interfaces.
Copyright © 2003 Pearson Education, Inc.
Slide 6-25
Change class headers to implement an interface
// Change class SalaryEmployee header
public class SalaryEmployee extends NewEmployee
implements Payable {
// Change class HourlyEmployee header
public class HourlyEmployee extends NewEmployee
implements Payable {
// In client of employee classes
NewEmployee temp = employees[i];
if (temp instanceof Payable)
weekPay = temp.calcWeeklyPay();
else
weekPay = 0.0;
Get next employee
from an array of
employee objects.
Call calc . . . if temp
references an object that
implements Payable.
Why can’t class NewEmployee implement Payable?
Copyright © 2003 Pearson Education, Inc.
Slide 6-26
Interface Comparable and method compareTo()
Java provides a Comparable interface. If a class implements
Comparable, you can compare its objects.
public interface Comparable {
public int compareTo(Object obj);
}
Method compareTo() returns an integer result:
The result is negative if the object it is applied to is less than the
argument.
The result is zero if the object it is applied to is equal to the
argument.
The result is positive if the object it is applied to is greater than
the argument.
Copyright © 2003 Pearson Education, Inc.
Slide 6-27
Class String implements Comparable
Method call
Result
"this".compareTo("that")
"that".compareTo("this")
"same".compareTo("same")
positive
negative
zero
Copyright © 2003 Pearson Education, Inc.
Reason
"this" > "that"
"that" < "this"
"same" == "same"
Slide 6-28
Sorting an array of Comparable objects
// postcondition: elements in array x are in increasing order
public static void selectionSort(Comparable[] x) {
int posMin;
Comparable temp;
//index of next smallest element
//temporary value for exchange
for (int fill = 0; fill < x.length-1; fill++) {
//Find index of smallest element in subarray
posMin = findPosMin(x, fill);
//Exchange elements with indices fill and posMin.
temp = x[fill]; x[fill] = x[posMin]; x[posMin] = temp;
}
}
private static int findPosMin(Comparable[] x, int fill) {
int posMinSoFar = fill;
for (int i = fill + 1; i < x.length; i++)
if (x[i].compareTo(x[posMinSoFar]) < 0)
posMinSoFar = i;
}
return posMinSoFar;
Copyright © 2003 Pearson Education, Inc.
Slide 6-29
6.5 Abstract classes
• An abstract class should not be instantiated.
• Its serves as the parent (superclass) of a group of related classes.
• The abstract class is a convenient place to declare data fields and methods
common to the related subclasses.
Form:
className {
data field declarations
abstract method headings
method definitions
public abstract class
}
Example:
public abstract class Food {
// Data field
private double calories;
// Abstract method
public abstract double percentProtein();
}
// Methods
public double getCalories() {return calories; }
public void setCalories(double cal) {
calories = cal;
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-30
Case study: Areas of geometric figures
PROBLEM: Find the total area of a collection of different geometric figures
and shapes.
ANALYSIS: Store objects of different figure types in a single array whose
elements are type GeoFigure(an abstract class). All our figure types extend this
class. We create a new geometric object by instantiating one of its subclasses,
not GeoFigure.
GeoFigure
Rectangle
Copyright © 2003 Pearson Education, Inc.
Circle
Triangle
Slide 6-31
Design of classes GeoFigure and Rectangle
Abstract Class GeoFigure
Methods
abstract double computePerimeter()
abstract double computeArea()
Class Rectangle
Data fields
Methods, cont’d
int width
int height
double computeArea()
void setWidth(int)
void setHeight(int)
int getWidth()
int getHeight()
String toString()
Methods
Rectangle()
Rectangle(int, int)
Copyright © 2003 Pearson Education, Inc.
Slide 6-32
Design of classes Circle and Triangle
Class Circle
Data fields
Methods, cont’d.
int radius
double computeArea()
void setRadius(int)
int getRadius()
String toString()
Methods
Circle()
Circle(int)
double computePerimeter()
Class Triangle
Data fields
int base
int height
Methods
Triangle()
Triangle(int, int)
double computePerimeter()
Copyright © 2003 Pearson Education, Inc.
Methods, cont’d.
double computeArea()
void setBase(int)
void setHeight(int)
int getBase()
int getHeight()
String toString()
Slide 6-33
Implementation of GeoFigure and Rectangle
public abstract class GeoFigure {
public abstract double computePerimeter();
public abstract double computeArea();
}
public class Rectangle extends GeoFigure {
// Data Fields
protected int width;
protected int height;
// Methods
// Constructors
public Rectangle() {}
public Rectangle(int wid, int hei) {
width = wid;
height = hei;
}
// Modifiers
public double computeArea() {
return height * width;
}
public double computePerimeter() {
return 2 * (height + width);
}
public String toString() {
return "Rectangle: width is " + width + ", height is "+ height;
}
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-34
Implementation of class TestGeoFigure
import java.awt.*;
public class TestGeoFigure {
public static void main(String[] args) {
// Create an array of type GeoFigure
GeoFigure gF[] = {new Triangle(10, 25),
new Circle(5),
new Rectangle(10, 20),
new Rectangle(30, 30)
};
// Compute area of each figure and add it to total.
// Display each figure and its area.
double totalArea = 0;
for (int i = 0; i < gF.length; i++) {
double area = gF[i].computeArea();
totalArea += area;
System.out.println(gF[i].toString());
System.out.println("Area is " + area + "\n");
}
}
System.out.println("\nTotal area is " + totalArea);
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-35
Sample run of class TestGeoFigure
Copyright © 2003 Pearson Education, Inc.
Slide 6-36
6.6 Drawing figures using Drawable interface
PROBLEM: We want to draw geometric figures on the screen. Each figure
object will be a standard shape and can be anywhere on the screen with any
interior color or border color.
ANALYSIS: We can extend classes Circle, Rectangle, and Triangle to get
three new subclasses for drawable figures (DrawableCircle,
DrawableRectangle, and DrawableTriangle). Each drawable class must
implement interface Drawable.
GeoFigure
Circle
Rectangle
Triangle
Drawable
DrawableRectangle
DrawableCircle
Copyright © 2003 Pearson Education, Inc.
DrawableTriangle
Slide 6-37
Design of class GeoFigure (new)
Data fields
Attributes
Point pos
Color borderColor
Color interiorColor
(x, y) position on screen
border color
interior color
Abstract Methods
Behavior
double computePerimeter()
double computeArea()
Computes the perimeter.
Computes the area.
Methods
Behavior
void setPoint(Point)
void setBorderColor(Color)
void setInteriorColor(Color)
Sets the (x, y) screen position.
Sets the border color to its argument.
Sets the interior color to its argument.
Point getPoint()
Color getBorderColor()
Color getInteriorColor()
Retrieves the (x, y) screen position.
Retrieves the border color.
Retrieves the interior color.
Copyright © 2003 Pearson Education, Inc.
Slide 6-38
Design of class DrawableRectangle
Methods
DrawableRectangle()
DrawableRectangle(int, int, Point,
Color, Color)
void drawMe(Graphics)
String toString()
Behavior
•No parameter constructor.
•Five parameter constructor.
•Draws a rectangle on the screen.
•Represents DrawableRectangle
object as a string.
Data Fields Inherited from Rectangle, GeoFigure
width, height, pos, borderColor,
interiorColor
Methods Inherited from Rectangle, GeoFigure
computePerimeter(), computeArea(),
setWidth(), setHeight(), setPos(),
setBorderColor(),
setInteriorColor(), getWidth(),
getHeight(), getPos(),
getInteriorColor(),
getBorderColor()
Copyright © 2003 Pearson Education, Inc.
Slide 6-39
Implementation of class GeoFigure
import java.awt.*;
public abstract class GeoFigure {
// Data Fields
protected Point pos = new Point(0, 0); // screen position
protected Color borderColor = Color.black;
protected Color interiorColor = Color.white;
// Abstract Methods
public abstract double computePerimeter();
public abstract double computeArea();
// Actual Methods
// Setters
public void setBorderColor(Color bor) {
borderColor = bor;
}
public void setInteriorColor(Color inter) {
interiorColor = inter;
}
public void setPoint(Point p) {
pos = p;
}
// Accessors
public Point getPos() { return pos; }
public Color getBorderColor() { return borderColor; }
public Color getInteriorColor() { return interiorColor; }
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-40
Implementation of class DrawableRectangle
import java.awt.*;
public class DrawableRectangle extends Rectangle
implements Drawable {
// Methods
// Constructors
public DrawableRectangle() {}
public DrawableRectangle(int wid, int hei,
Point p, Color bor, Color inter) {
super(wid, hei); // Define width and height fields
pos = p;
borderColor = bor;
interiorColor = inter;
}
// postcondition: Draws a rectangular object with
//
top-left corner at pos.x, pos.y
public void drawMe(Graphics g) {
Point data
g.setColor(interiorColor);
g.fillRect(pos.x, pos.y, width, height);
fields x and y
g.setColor(borderColor);
are public
g.drawRect(pos.x, pos.y, width, height);
}
public String toString() {
return "Drawable " + super.toString() +
"\nx coordinate is " + pos.x +
", y coordinate is " + pos.y +
"\nborder color is " + borderColor +
"\ninterior color is " + interiorColor;
}
}
Copyright © 2003 Pearson Education, Inc.
Slide 6-41
Implementation of class TestGeoFigure
import java.awt.*;
import java.applet.Applet;
public class TestDrawFigures extends Applet {
public void paint(Graphics g) {
// Create an array of type GeoFigure
GeoFigure gf[] = {
new DrawableRectangle(100, 100, new Point(0,0),
Color.blue, Color.green),
new DrawableRectangle(100, 200, new Point(100,100),
Color.red, Color.yellow),
new Triangle(10, 20),
new DrawableRectangle(50, 100, new Point(200,300),
Color.black, Color.red),
new DrawableCircle(30, new Point(300,200),
Color.orange, Color.gray),
new DrawableTriangle(40, 60,
new Point(300,300),
Color.black, Color.magenta) };
}
}
// Draw the drawable objects.
for (int i = 0; i < gf.length; i++) {
if (gf[i] instanceof Drawable)
((Drawable) gf[i]).drawMe(g);
}
Cast object
and draw it.
Copyright © 2003 Pearson Education, Inc.
Slide 6-42
Sample run of class TestDrawableFigures
Copyright © 2003 Pearson Education, Inc.
Slide 6-43
6.7 Packages and visibility
• Declare the package to which a class belongs at the top of the file using
the keyword package followed by the package name. For example,
package psJava;
• Store all classes in the same package in the same directory or folder. The
directory should have the same name as the package. All the classes in the
folder must declare themselves to be in the package.
•Classes that are not part of a package may access public members (data
fields or methods) of classes in the package.
•The import statement allows class members to be referenced directly by
their class name. The statement
import javax.swing.*;
allows us to reference methods in package swing by name.
•Without the import statement, we would use
swingx.JOptionPane.showMessageDialog(". . . ");
to call the method.
Copyright © 2003 Pearson Education, Inc.
Slide 6-44
Summary of kinds of visibility
Visibility
private
Default or
package
protected
public
Applied to class
Applied to class
members
Not applicable
Visible only within this
class.
Accessible to classes Accessible to classes in
in this package
this package
Not applicable
Accessible to classes in
this package and to
classes outside this
package that extend the
class.
Accessible to all
Accessible to all
classes
classes. The class
defining the member
must also be public.
Copyright © 2003 Pearson Education, Inc.
Slide 6-45
6.8 Testing a program system
A stub consists of a method heading followed by a minimal body, which should
display a message identifying the method being executed. If the stub is a
mutator, it should assign simple values to any data fields it is supposed to
modify.
public double computeArea() {
System.out.println("Executing computeArea() in class Triangle");
return 100.0;
}
Perform a preliminary test of a new method or class because it is easier to
locate and correct errors when dealing with a single entity rather than with a
complete program system. We can perform a unit test of a method by writing
a driver method to call it.
public static void main(String[] args) {
Triangle tr = new Triangle(10, 20);
}
System.out.println("Triangle area is " +
tr.computeArea());
Copyright © 2003 Pearson Education, Inc.
Slide 6-46
Different testing methods
•Testing overall flow of control using stubs is called top-down
testing.
•Testing individual methods and classes using drivers is called
bottom-up testing. You can insert a main( ) method in each new
class to test its methods or write a separate application class.
•Testing all the classes of a program system together is called
system-integration testing.
•Testing a program without knowledge of the code is called
black-box or specification based testing.
•Viewing the code and testing each code fragment thoroughly is
called white-box or glass-box testing.
Copyright © 2003 Pearson Education, Inc.
Slide 6-47