Programming Notes PDF
Programming Notes PDF
| HOME
TABLE OF CONTENTS (HIDE)
1. Exercises on Classes
1.1 Ex: The Circle Class (An Introduction to Classes and Instances)
1.2 Ex: A Simplified Circle Class
1.3 Ex: The Rectangle Class
1.4 Ex: The Employee Class
1.5 Ex: The InvoiceItem Class
1.6 Ex: The Account Class
1.7 Ex: The Date Class
1.8 Ex: The Time Class
2. Exercises on Composition
2.1 Ex: The Author and Book Classes (An Introduction to OOP Composition)
2.2 Exercise (Advanced): Book and Author Classes Again - An Array of Objects as an Instance
Variable
2.3 Ex: The MyPoint Class
2.4 Ex: The MyCircle and MyPoint Classes
2.5 Ex: The MyTriangle and MyPoint Classes
2.6 Ex: The MyRectangle and MyPoint Classes
2.7 Ex: The Customer and Invoice classes
2.8 Ex: The Customer and Account classes
3. More Exercises on Classes
3.1 Ex: The MyComplex class
3.2 Ex: The MyPolynomial Class
3.3 Ex: Using JDK's BigInteger Class
3.4 Ex: The MyTime Class
3.5 Ex: The MyDate Class
3.6 Ex: Bouncing Balls - Ball and Container Classes
3.7 Ex: The Ball and Player Classes
4. Exercises on Inheritance
4.1 Ex: The Circle and Cylinder Classes
4.2 Ex: Superclass Person and its subclasses
4.3 Ex: Point2D and Point3D
4.4 Ex: Point and MovablePoint
4.5 Ex: Superclass Shape and its subclasses Circle, Rectangle and Square
5. Exercises on Composition vs Inheritance
5.1 Ex: The Point and Line Classes
5.2 Ex: The Circle and Cylinder Classes Using Composition
6. Exercises on Polymorphism, Abstract Classes and Interfaces
6.1 Ex: Abstract Superclass Shape and Its Concrete Subclasses
6.2 Ex: Polymorphism
6.3 Ex: Interface Movable and its implementations MovablePoint and MovableCircle
6.4 Ex: Interfaces GeometricObject and Resizable
7. More Exercises on OOP
7.1 Ex: The Discount System
7.2 Ex: Polyline of Points with ArrayList
8. Exercises on Data Structures
8.1 Ex: MyIntStack
A class called circle is designed as shown in the following class diagram. It contains:
Two private instance variables: radius (of the type double) and color (of the type String), with
default value of 1.0 and "red", respectively.
Two overloaded constructors - a default constructor with no argument, and a constructor which
takes a double argument for radius.
Two public methods: getRadius() and getArea(), which return the radius and area of this
instance, respectively.
The source codes for Circle.java is as follows:
/*
* The Circle class models a circle with a radius and color.
*/
public class Circle { // Save as "Circle.java"
// private instance variable, not accessible from outside this class
private double radius;
private String color;
Modify the test program TestCircle to construct an instance of Circle using this constructor.
3. Getter: Add a getter for variable color for retrieving the color of this instance.
4. // Getter for instance variable color
13. Keyword "this": Instead of using variable names such as r (for radius) and c (for color)
in the methods' arguments, it is better to use variable names radius (for radius)
and color (for color) and use the special keyword "this" to resolve the conflict between
instance variables and methods' arguments. For example,
14. // Instance variable
15. private double radius;
16.
17. // Constructor
18. public Circle(double radius) {
19. this.radius = radius; // "this.radius" refers to the instance variable
20. // "radius" refers to the method's parameter
21. color = .......
22. }
23.
24. // Setter of radius
25. public void setRadius(double radius) {
26. this.radius = radius; // "this.radius" refers to the instance variable
27. // "radius" refers to the method's argument
Modify ALL the constructors and setters in the Circle class to use the keyword "this".
28. Method toString(): Every well-designed Java class should contain a public method
called toString() that returns a short description of the instance (in a return type of String).
ThetoString() method can be called explicitly (via instanceName.toString()) just like any
other method; or implicitly through println(). If an instance is passed to
the println(anInstance)method, the toString() method of that instance will be invoked
implicitly. For example, include the following toString() methods to the Circle class:
29. // Return a description of this instance in the form of
30. // Circle[radius=r,color=c]
31. public String toString() {
32. return "Circle[radius=" + radius + " color=" + color + "]";
Try calling toString() method explicitly, just like any other method:
toString() is called implicitly when an instance is passed to println() method, for example,
2. Exercises on Composition
2.1 Ex: The Author and Book Classes (An Introduction to OOP
Composition)
This first exercise shall lead you through all the concepts involved in OOP Composition.
A class called Author (as shown in the class diagram) is designed to model a book's author. It contains:
Three private instance variables: name (String), email (String), and gender (char of
either 'm' or 'f');
One constructor to initialize the name, email and gender with the given values;
(There is no default constructor for Author, as there are no defaults for name, email and gender.)
public getters/setters: getName(), getEmail(), setEmail(), and getGender();
(There are no setters for name and gender, as these attributes cannot be changed.)
A toString() method that returns "Author[name=?,email=?,gender=?] ", e.g.,
"Author[name=Tan Ah Teck,email=ahTeck@somewhere.com,gender=m] ".
Write the Author class. Also write a test driver called TestAuthor to test all the public methods, e.g.,
Author ahTeck = new Author("Tan Ah Teck", "ahteck@nowhere.com", 'm'); // Test the
constructor
System.out.println(ahTeck); // Test toString()
ahTeck.setEmail("paulTan@nowhere.com"); // Test setter
System.out.println("name is: " + ahTeck.getName()); // Test getter
System.out.println("eamil is: " + ahTeck.getEmail()); // Test getter
System.out.println("gender is: " + ahTeck.getGender()); // Test
gExerciseOOP_MyPolynomial.pngetter
A class called Book is designed (as shown in the class diagram) to model a book written by one author.
It contains:
Four private instance variables: name (String), author (of the class Author you have just
created, assume that a book has one and only one author), price (double), and qty (int);
Two constructors:
public Book (String name, Author author, double price, int qty) { ...... }
Take note that both Book and Author classes have a variable called name. However, it can be
differentiated via the referencing instance. For a Book instance says aBook, aBook.name refers to
the name of the book; whereas for an Author's instance say auAuthor, anAuthor.name refers to
the name of the author. There is no need (and not recommended) to call the
variables bookName and authorName.
TRY:
1. Printing the name and email of the author from a Book instance.
(Hint: aBook.getAuthor().getName() , aBook.getAuthor().getEmail()).
2. Introduce new methods called getAuthorName(), getAuthorEmail(), getAuthorGender() in
the Book class to return the name, email and gender of the author of the book. For example,
Notes:
The constructors take an array of Author (i.e., Author[]), instead of an Author instance. In this
design, once a Book instance is constructor, you cannot add or remove author.
The toString() method shall return
"Book[name=?,authors={Author[name=?,email=?,gender=?],......},price=?,qty=?] ".
System.out.println(p1.distance(5, 6));
An overloaded distance(MyPoint another) that returns the distance from this point to the
given MyPoint instance (called another), e.g.,
System.out.println(p1.distance(p2));
Another overloaded distance() method that returns the distance from this point to the
origin (0,0), e.g.,
System.out.println(p1.distance());
}
// Test program to test all constructors and public methods
MyPoint p1 = new MyPoint(); // Test constructor
System.out.println(p1); // Test toString()
p1.setX(8); // Test setters
p1.setY(6);
System.out.println("x is: " + p1.getX()); // Test getters
System.out.println("y is: " + p1.getY());
p1.setXY(3, 0); // Test setXY()
System.out.println(p1.getXY()[0]); // Test getXY()
System.out.println(p1.getXY()[1]);
System.out.println(p1);
14. Write a program that allocates 10 points in an array of MyPoint, and initializes to (1, 1), (2,
2), ... (10, 10).
Hints: You need to allocate the array, as well as each of the 10 MyPoint instances. In other
words, you need to issue 11 new, 1 for the array and 10 for the MyPoint instances.
15. MyPoint[] points = new MyPoint[10]; // Declare and allocate an array of MyPoint
16. for (int i = 0; i < points.length; i++) {
17. points[i] = new MyPoint(...); // Allocate each of MyPoint instances
18. }
19. // use a loop to print all the points
Notes: Point is such a common entity that JDK certainly provided for in all flavors.
2.4 Ex: The MyCircle and MyPoint Classes
A class called MyCircle, which models a circle with a center (x,y) and a radius, is designed as shown
in the class diagram. The MyCircle class uses an instance of MyPoint class (created in the previous
exercise) as its center.
// Returns the distance of the center for this MyCircle and another MyCircle
public double distance(MyCircle another) {
return center.distance(another.center); // use distance() of MyPoint
}
It contains:
Three private instance variables v1, v2, v3 (instances of MyPoint), for the three vertices.
A constructor that constructs a MyTriangle with three set of coordinates, v1=(x1, y1), v2=(x2,
y2), v3=(x3, y3).
An overloaded constructor that constructs a MyTriangle given three instances of MyPoint.
A toString() method that returns a string description of the instance in the format
"MyTriangle[v1=(x1,y1),v2=(x2,y2),v3=(x3,y3)]".
A getPerimeter() method that returns the length of the perimeter in double. You should use
the distance() method of MyPoint to compute the perimeter.
A method printType(), which prints "equilateral" if all the three sides are equal, "isosceles"
if any two of the three sides are equal, or "scalene" if the three sides are different.
Write the MyTriangle class. Also write a test driver (called TestMyTriangle) to test all
the public methods defined in the class.
2.6 Ex: The MyRectangle and MyPoint Classes
Design a MyRectangle class which is composed of two MyPoint instances as its top-left and bottom-
right corners. Draw the class diagrams, write the codes, and write the test drivers.
2.7 Ex: The Customer and Invoice classes
The Customer class models a customer is design as shown in the class diagram. Write the codes for
the Customer class and a test driver to test all the public methods.
The Invoice class, design as shown in the class diagram, composes a Customer instance (written
earlier) as its member. Write the codes for the Invoice class and a test driver to test all
the public methods.
2.8 Ex: The Customer and Account classes
The Customer class models a customer is design as shown in the class diagram. Write the codes for
the Customer class and a test driver to test all the public methods.
The Account class models a bank account, design as shown in the class diagram, composes
a Customer instance (written earlier) as its member. Write the codes for the Account class and a test
driver to test all the public methods.
3. More Exercises on Classes
3.1 Ex: The MyComplex class
A class called MyComplex, which models complex numbers x+yi, is designed as shown in the class
diagram. It contains:
Two instance variable named real (double) and imag (double) which stores the real and
imaginary parts of the complex number, respectively.
A constructor that creates a MyComplex instance with the given real and imaginary values.
A default constructor that create a MyComplex at 0.0 + 0.0i.
Getters and setters for instance variables real and imag.
A method setValue() to set the value of the complex number.
A toString() that returns "(x + yi)" where x and y are the real and imaginary parts,
respectively.
Methods isReal() and isImaginary() that returns true if this complex number is real or
imaginary, respectively.
Hints:
return (imag == 0);
A method equals(double real, double imag) that returns true if this complex number is
equal to the given complex number (real, imag).
Hints:
An overloaded equals(MyComplex another) that returns true if this complex number is equal to
the given MyComplex instance another.
Hints:
Methods argument() that returns the argument of this complex number in radians (double).
Hints:
return this; // return "this" instance
A method conjugate() that operates on this instance and returns this instance containing
the complex conjugate.
conjugate(x+yi) = x - yi
Take note that there are a few flaws in the design of this class, which was introduced solely for teaching
purpose:
Comparing doubles in equal() using "==" may produce unexpected outcome. For
example, (2.2+4.4)==6.6 returns false. It is common to define a small threshold
called EPSILON (set to about10^-8) for comparing floating point numbers.
The method addNew(), subtractNew() produce new instances,
whereas add(), subtract(), multiply(), divide() and conjugate() modify this instance.
There is inconsistency in the design (introduced for teaching purpose).
Also take note that methods such as add() returns an instance of MyComplex. Hence, you can place
the result inside a System.out.println() (which implicitly invoke the toString()). You can also chain
the operations, e.g., c1.add(c2).add(c3) (same as (c1.add(c2)).add(c3)),
or c1.add(c2).subtract(c3).
3.2 Ex: The MyPolynomial Class
A class called MyPolynomial, which models polynomials of degree-n (see equation), is designed as
shown in the class diagram.
It contains:
An instance variable named coeffs, which stores the coefficients of the n-degree polynomial in
a double array of size n+1, where c0 is kept at index 0.
A constructor MyPolynomial(coeffs:double...) that takes a variable number of doubles to
initialize the coeffs array, where the first argument corresponds to c0.
The three dots is known as varargs (variable number of arguments), which is a new feature
introduced in JDK 1.5. It accepts an array or a sequence of comma-separated arguments. The
compiler automatically packs the comma-separated arguments in an array. The three dots can
only be used for the last argument of the method.
Hints:
Hints:
import java.math.BigInteger
public class TestBigInteger {
public static void main(String[] args) {
BigInteger i1 = new BigInteger(...);
BigInteger i2 = new BigInteger(...);
System.out.println(i1.add(i2));
.......
}
}
A class called MyDate, which models a date instance, is defined as shown in the class diagram.
The MyDate class contains the following private instance variables:
year (int): Between 1 to 9999.
month (int): Between 1 (Jan) to 12 (Dec).
day (int): Between 1 to 28|29|30|31, where the last day depends on the month and whether it is
a leap year for Feb (28|29).
It also contains the following private static variables (drawn with underlined in the class diagram):
strMonths (String[]), strDays (String[]), and dayInMonths (int[]): static variables,
initialized as shown, which are used in the methods.
The MyDate class has the following public static methods (drawn with underlined in the class
diagram):
isLeapYear(int year): returns true if the given year is a leap year. A year is a leap year if it is
divisible by 4 but not by 100, or it is divisible by 400.
isValidDate(int year, int month, int day): returns true if the given year, month,
and day constitute a valid date. Assume that year is between 1 and 9999, month is
between 1 (Jan) to 12(Dec) and day shall be between 1 and 28|29|30|31 depending on
the month and whether it is a leap year on Feb.
getDayOfWeek(int year, int month, int day): returns the day of the week, where 0 for
Sun, 1 for Mon, ..., 6 for Sat, for the given date. Assume that the date is valid. Read the earlier
exercise on how to determine the day of the week (or Wiki "Determination of the day of the
week").
The MyDate class has one constructor, which takes 3 parameters: year, month and day. It shall
invoke setDate() method (to be described later) to set the instance variables.
The MyDate class has the following public methods:
setDate(int year, int month, int day): It shall invoke the static method isValidDate() to
verify that the given year, month and day constitute a valid date.
(Advanced: Otherwise, it shall throw an IllegalArgumentException with the message "Invalid
year, month, or day!".)
setYear(int year): It shall verify that the given year is between 1 and 9999.
(Advanced: Otherwise, it shall throw an IllegalArgumentException with the message "Invalid
year!".)
setMonth(int month): It shall verify that the given month is between 1 and 12.
(Advanced: Otherwise, it shall throw an IllegalArgumentException with the message "Invalid
month!".)
setDay(int day): It shall verify that the given day is between 1 and dayMax,
where dayMax depends on the month and whether it is a leap year for Feb.
(Advanced: Otherwise, it shall throw an IllegalArgumentException with the message "Invalid
month!".)
getYear(), getMonth(), getDay(): return the value for the year, month and day, respectively.
toString(): returns a date string in the format "xxxday d mmm yyyy", e.g., "Tuesday 14 Feb 2012".
nextDay(): update this instance to the next day and return this instance. Take note
that nextDay() for 31 Dec 2000 shall be 1 Jan 2001.
nextMonth(): update this instance to the next month and return this instance. Take note
that nextMonth() for 31 Oct 2012 shall be 30 Nov 2012.
nextYear(): update this instance to the next year and return this instance. Take note
that nextYear() for 29 Feb 2012 shall be 28 Feb 2013.
(Advanced: throw an IllegalStateException with the message "Year out of range!" if year >
9999.)
previousDay(), previousMonth(), previousYear(): similar to the above.
Write the code for the MyDate class.
Use the following test statements to test the MyDate class:
Write a test program that tests the nextDay() in a loop, by printing the dates from 28 Dec 2011 to 2
Mar 2012.
3.6 Ex: Bouncing Balls - Ball and Container Classes
A class called Ball is designed as shown in the class diagram.
The Ball class contains the following private instance variables:
x, y and radius, which represent the ball's center (x, y) co-ordinates and the radius,
respectively.
xDelta (Δx) and yDelta (Δy), which represent the displacement (movement) per step, in
the x and y direction respectively.
The Ball class contains the following public methods:
A constructor which accepts x, y, radius, speed, and direction as arguments. For user
friendliness, user specifies speed (in pixels per step) and direction (in degrees in the range of (-
180°, 180°]). For the internal operations, the speed and direction are to be converted to (Δx,
Δy) in the internal representation. Note that the y-axis of the Java graphics coordinate system is
inverted, i.e., the origin (0, 0) is located at the top-left corner.
Δx = d × cos(θ)
Δy = -d × sin(θ)
x += Δx
y += Δy
reflectHorizontal() which reflects the ball horizontally (i.e., hitting a vertical wall)
Δx = -Δx
Δy no changes
Δx no changes
Δy = -Δy
toString() which prints the message "Ball at (x, y) of velocity (Δx, Δy) ".
Write the Ball class. Also write a test program to test all the methods defined in the class.
A class called Container, which represents the enclosing box for the ball, is designed as shown in the
class diagram. It contains:
Instance variables (x1, y1) and (x2, y2) which denote the top-left and bottom-right corners of
the rectangular box.
A constructor which accepts (x, y) of the top-left corner, width and height as argument, and
converts them into the internal representation (i.e., x2=x1+width-1). Width and height is used in
the argument for safer operation (there is no need to check the validity of x2>x1 etc.).
A toString() method that returns "Container at (x1,y1) to (x2, y2)".
A boolean method called collidesWith(Ball), which check if the given Ball is outside the
bounds of the container box. If so, it invokes
the Ball's reflectHorizontal() and/orreflectVertical() to change the movement direction
of the ball, and returns true.
The Ball class, which models the ball in a soccer game, is designed as shown in the class diagram.
Write the codes for the Ball class and a test driver to test all the public methods.
The Player class, which models the players in a soccer game, is designed as shown in the class
diagram. The Player interacts with the Ball (written earlier). Write the codes for the Player class and a
test driver to test all the public methods. Make your assumption for the kick().
Can you write a very simple soccer game with 2 teams of players and a ball, inside a soccer field?
4. Exercises on Inheritance
4.1 Ex: The Circle and Cylinder Classes
This exercise shall guide you through the important concepts in inheritance.
In this exercise, a subclass called Cylinder is derived from the superclass Circle as shown in the class
diagram (where an an arrow pointing up from the subclass to its superclass). Study how the
subclassCylinder invokes the superclass' constructors (via super() and super(radius)) and inherits
the variables and methods from the superclass Circle.
You can reuse the Circle class that you have created in the previous exercise. Make sure that you
keep "Circle.class" in the same directory.
public class Cylinder extends Circle { // Save as "Cylinder.java"
private double height; // private variable
// Constructor with default color, radius and height
public Cylinder() {
super(); // call superclass no-arg constructor Circle()
height = 1.0;
}
// Constructor with default radius, color but given height
public Cylinder(double height) {
super(); // call superclass no-arg constructor Circle()
this.height = height;
}
// Constructor with default color, but given radius, height
public Cylinder(double radius, double height) {
super(radius); // call superclass constructor Circle(r)
this.height = height;
}
Write a test program (says TestCylinder) to test the Cylinder class created, as follow:
public class TestCylinder { // save as "TestCylinder.java"
public static void main (String[] args) {
// Declare and allocate a new instance of cylinder
// with default color, radius, and height
Cylinder c1 = new Cylinder();
System.out.println("Cylinder:"
+ " radius=" + c1.getRadius()
+ " height=" + c1.getHeight()
+ " base area=" + c1.getArea()
+ " volume=" + c1.getVolume());
Method Overriding and "Super": The subclass Cylinder inherits getArea() method from
its superclass Circle. Try overriding the getArea() method in the subclass Cylinder to compute the
surface area (=2π×radius×height + 2×base-area) of the cylinder instead of base area. That is,
if getArea() is called by a Circle instance, it returns the area. If getArea() is called by
a Cylinder instance, it returns the surface area of the cylinder.
If you override the getArea() in the subclass Cylinder, the getVolume() no longer works. This is
because the getVolume() uses the overridden getArea() method found in the same class. (Java
runtime will search the superclass only if it cannot locate the method in this class). Fix the getVolume().
Hints: After overridding the getArea() in subclass Cylinder, you can choose to invoke
the getArea() of the superclass Circle by calling super.getArea().
TRY:
Provide a toString() method to the Cylinder class, which overrides the toString() inherited from
the superclass Circle, e.g.,
@Override
public String toString() { // in Cylinder class
return "Cylinder: subclass of " + super.toString() // use Circle's toString()
+ " height=" + height;
}
Override the toString() method to return "A Square with side=xxx, which is a subclass
of yyy", where yyy is the output of the toString() method from the superclass.
Do you need to override the getArea() and getPerimeter()? Try them out.
Override the setLength() and setWidth() to change both the width and length, so as to
maintain the square geometry.
5. Exercises on Composition vs Inheritance
They are two ways to reuse a class in your applications: composition and inheritance.
5.1 Ex: The Point and Line Classes
Let us begin with composition with the statement "a line composes of two points".
Complete the definition of the following two classes: Point and Line. The class Line composes 2
instances of class Point, representing the beginning and ending points of the line. Also write test
classes forPoint and Line (says TestPoint and TestLine).
public class Point {
// Private variables
private int x; // x co-ordinate
private int y; // y co-ordinate
// Constructor
public Point (int x, int y) {......}
// Public methods
public String toString() {
return "Point: (" + x + "," + y + ")";
}
// Constructors
public Line (Point begin, Point end) { // caller to construct the Points
this.begin = begin;
......
}
public Line (int beginX, int beginY, int endX, int endY) {
begin = new Point(beginX, beginY); // construct the Points here
......
}
// Public methods
public String toString() { ...... }
The class diagram for composition is as follows (where a diamond-hollow-head arrow pointing to its
constituents):
Instead of composition, we can design a Line class using inheritance. Instead of "a line composes of
two points", we can say that "a line is a point extended by another point", as shown in the following
class diagram:
Let's re-design the Line class (called LineSub) as a subclass of class Point. LineSub inherits the
starting point from its superclass Point, and adds an ending point. Complete the class definition. Write
a testing class called TestLineSub to test LineSub.
public class LineSub extends Point {
// A line needs two points: begin and end.
// The begin point is inherited from its superclass Point.
// Private variables
Point end; // Ending point
// Constructors
public LineSub (int beginX, int beginY, int endX, int endY) {
super(beginX, beginY); // construct the begin Point
this.end = new Point(endX, endY); // construct the end Point
}
public LineSub (Point begin, Point end) { // caller to construct the Points
super(begin.getX(), begin.getY()); // need to reconstruct the begin Point
this.end = end;
}
// Public methods
// Inherits methods getX() and getY() from superclass Point
public String toString() { ... }
Summary: There are two approaches that you can design a line, composition or inheritance. "A line
composes two points" or "A line is a point extended with another point"”. Compare
the Line andLineSub designs: Line uses composition and LineSub uses inheritance. Which design is
better?
5.2 Ex: The Circle and Cylinder Classes Using Composition
Try rewriting the Circle-Cylinder of the previous exercise using composition (as shown in the class
diagram) instead of inheritance. That is, "a cylinder is composed of a base circle and a height".
public class Cylinder {
private Circle base; // Base circle, an instance of Circle class
private double height;
Write a test class to test these statements involving polymorphism and explain the outputs. Some
statements may trigger compilation errors. Explain the errors, if any.
Explain the outputs (or error) for the following test program.
// Using Polymorphism
Animal animal1 = new Cat();
animal1.greeting();
Animal animal2 = new Dog();
animal2.greeting();
Animal animal3 = new BigDog();
animal3.greeting();
Animal animal4 = new Animal();
// Downcast
Dog dog2 = (Dog)animal2;
BigDog bigDog2 = (BigDog)animal3;
Dog dog3 = (Dog)animal3;
Cat cat2 = (Cat)animal2;
dog2.greeting(dog3);
dog3.greeting(dog2);
dog2.greeting(bigDog2);
bigDog2.greeting(dog2);
bigDog2.greeting(bigDog1);
}
}
For the MovablePoint class, declare the instance variable x, y, xSpeed and ySpeed with package access
as shown with '~' in the class diagram (i.e., classes in the same package can access these variables
directly). For the MovableCircle class, use a MovablePoint to represent its center (which contains four
variable x, y, xSpeed and ySpeed). In other words, the MovableCircle composes a MovablePoint, and
its radius.
public class MovablePoint implements Movable { // saved as "MovablePoint.java"
// instance variables
int x, y, xSpeed, ySpeed; // package access
// Constructor
public MovablePoint(int x, int y, int xSpeed, int ySpeed) {
this.x = x;
......
}
......
// Constructor
public MovableCircle(int x, int y, int xSpeed, int ySpeed, int radius) {
// Call the MovablePoint's constructor to allocate the center instance.
center = new MovablePoint(x, y, xSpeed, ySpeed);
......
}
......
5. Write the implementation class Circle, with a protected variable radius, which implements the
interface GeometricObject.
Hints:
6. public class Circle implements GeometricObject {
7. // Private variable
8. ......
9.
10. // Constructor
11. ......
12.
13. // Implement methods defined in the interface GeometricObject
14. @Override
15. public double getPerimeter() { ...... }
16.
17. ......
}
18. Write a test program called TestCircle to test the methods defined in Circle.
19. The class ResizableCircle is defined as a subclass of the class Circle, which also implements
an interface called Resizable, as shown in class diagram. The interface Resizable declares
anabstract method resize(), which modifies the dimension (such as radius) by the given
percentage. Write the interface Resizable and the class ResizableCircle.
Hints:
20. public interface Resizable {
21. public double resize(...);
}
public class ResizableCircle extends Circle implements Resizeable {
// Constructor
public ResizableCircle(double radius) {
super(...);
}
22. Write a test program called TestResizableCircle to test the methods defined
in ResizableCircle.
7. More Exercises on OOP
7.1 Ex: The Discount System
You are asked to write a discount system for a beauty saloon, which provides services and sells beauty
products. It offers 3 types of memberships: Premium, Gold and Silver. Premium, gold and silver
members receive a discount of 20%, 15%, and 10%, respectively, for all services provided. Customers
without membership receive no discount. All members receives a flat 10% discount on products
purchased (this might change in future). Your system shall consist of three
classes: Customer, Discount and Visit, as shown in the class diagram. It shall compute the total bill if
a customer purchases $x of products and $y of services, for a visit. Also write a test program to exercise
all the classes.
The class DiscountRate contains only static variables and methods (underlined in the class diagram).
7.2 Ex: Polyline of Points with ArrayList
A polyline is a line with segments formed by points. Let's use the ArrayList (dynamically allocated
array) to keep the points, but upcast to List in the instance variable. (Take note that array is of fixed-
length, and you need to set the initial length).
public class Point {
private int x;
private int y;
public Point(int x, int y) { ...... }
public int getX() { ...... }
public int getY() { ...... }
public void setX(int x) { ...... }
public void setY(int y) { ...... }
public int[] getXY() { ...... }
public void setXY(int x, int y) { ...... }
public String toString() { ...... }
public double distance(Point another) { ...... }
}
import java.util.*;
public class PolyLine {
private List<Point> points; // List of Point instances
// Constructors
public PolyLine() { // default constructor
points = new ArrayList<Point>(); // implement with ArrayList
}
public PolyLine(List<Point> points) {
this.points = points;
}
// Return {(x1,y1)(x2,y2)(x3,y3)....}
public String toString() {
// Use a StringBuilder to efficiently build the return String
StringBuilder sb = new StringBuilder("{");
for (Point aPoint : points) {
sb.append(aPoint.toString());
}
sb.append("}");
return sb.toString();
}
// Test appendPoint()
l1.appendPoint(new Point(1, 2));
l1.appendPoint(3, 4);
l1.appendPoint(5, 6);
System.out.println(l1); // {(1,2)(3,4)(5,6)}
// Test constructor 2
List<Point> points = new ArrayList<Point>();
points.add(new Point(11, 12));
points.add(new Point(13, 14));
PolyLine l2 = new PolyLine(points);
System.out.println(l2); // {(11,12)(13,14)}
}
}
Try:
1. Modify the push() method to throw an IllegalStateException if the stack is full.
2. Modify the push() to return true if the operation is successful, or false otherwise.
3. Modify the push() to increase the capacity by reallocating another array, if the stack is full.
Exercise (Nodes, Link Lists, Trees, Graphs):
[TODO]
Study the existing open source codes, including JDK.
Specialized algorithms, such as shortest path.
Exercise (Maps):
[TODO]
Representation of map data.
Specialized algorithms, such as shortest path.
[TODO]
Study the existing open source codes, including JDK's 2D Graphics and JOGL's 3D Graphics.
Efficient and specialized codes for 3D Graphics (4D matrices). Handle various primitive types such
as int, float and double efficiently.
Latest version tested: JDK 1.8.0
Last modified: April, 2016
Feedback, comments, corrections, and errata can be sent to Chua Hock-Chuan
(ehchua@ntu.edu.sg) | HOME