OOP Exercises - Java Programming Tutorial
OOP Exercises - Java Programming Tutorial
OOPExercisesJavaProgrammingTutorial
Java Programming
Tutorial
OOP Exercises
2.Exercises on Inheritance
2.1Exercise: The Circle and Cylinder
4.2Exercise: Polymorphism
4.3Exercise: Interface Movable and its impleme
4.4Exercise: Interfaces GeometricObject
1/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
//1stconstructor,whichsetsbothradiusandcolortodefault
publicCircle(){
radius=1.0;
color="red";
}
//2ndconstructorwithgivenradius,butcolordefault
publicCircle(doubler){
radius=r;
color="red";
}
//Apublicmethodforretrievingtheradius
publicdoublegetRadius(){
returnradius;
}
//Apublicmethodforcomputingtheareaofcircle
publicdoublegetArea(){
returnradius*radius*Math.PI;
}
}
Compile "Circle.java". Can you run the Circle class? Why? This Circle class does not have a main() method.
Hence, it cannot be run directly. This Circle class is a building block and is meant to be used in another
program.
Let us write a test program called TestCircle which uses the Circle class, as follows:
publicclassTestCircle{//saveas"TestCircle.java"
publicstaticvoidmain(String[]args){
//DeclareandallocateaninstanceofclassCirclecalledc1
//withdefaultradiusandcolor
Circlec1=newCircle();
//Usethedotoperatortoinvokemethodsofinstancec1.
System.out.println("Thecirclehasradiusof"
+c1.getRadius()+"andareaof"+c1.getArea());
//Declareandallocateaninstanceofclasscirclecalledc2
//withthegivenradiusanddefaultcolor
Circlec2=newCircle(2.0);
//Usethedotoperatortoinvokemethodsofinstancec2.
System.out.println("Thecirclehasradiusof"
+c2.getRadius()+"andareaof"+c2.getArea());
}
}
2/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
Modify the test program TestCircle to construct an instance of Circle using this constructor.
2. Getter: Add a getter for variable color for retrieving the color of a Circle instance.
//Getterforinstancevariablecolor
publicStringgetColor(){......}
//Setterforinstancevariablecolor
publicvoidsetColor(Stringc){......}
5. 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,
//Instancevariable
privatedoubleradius;
//Setterofradius
publicvoidsetRadius(doubleradius){
this.radius=radius;//"this.radius"referstotheinstancevariable
//"radius"referstothemethod'sargument
}
Modify ALL the constructors and setters in the Circle class to use the keyword "this".
6. Method toString(): Every welldesigned Java class should contain a public method called
toString() that returns a short description of the instance in a return type of String. The toString()
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:
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
3/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
publicStringtoString(){
return"Circle:radius="+radius+"color="+color;
}
Try calling toString() method explicitly, just like any other method:
Circlec1=newCircle(5.0);
System.out.println(c1.toString());//explicitcall
toString() is called implicitly when an instance is passed to println() method, for example,
Circlec2=newCircle(1.2);
System.out.println(c2.toString());//explicitcall
System.out.println(c2);//println()callstoString()implicitly,sameasabove
System.out.println("Operator'+'invokestoString()too:"+c2);//'+'invokestoString()too
private
instance
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 "authorname (gender) at email", e.g., "Tan Ah Teck m at
[email protected]".
Write the Author class. Also write a test program called TestAuthor to test the constructor and public methods.
Try changing the email of an author, e.g.,
AuthoranAuthor=newAuthor("TanAhTeck","[email protected]",'m');
System.out.println(anAuthor);//calltoString()
anAuthor.setEmail("[email protected]")
System.out.println(anAuthor);
4/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
publicBook(Stringname,Authorauthor,doubleprice,
intqtyInStock){...}
public methods
getName(),
getAuthor(),
getPrice(),
setPrice(),
getQtyInStock(), setQtyInStock().
toString() that returns "'bookname' by authorname (gender) at email".
Take note that the Author's toString() method returns "authorname (gender) at email".
Write the class Book which uses the Author class written earlier. Also write a test program called TestBook to test
the constructor and public methods in the class Book. Take Note that you have to construct an instance of Author
before you can construct an instance of Book. E.g.,
AuthoranAuthor=newAuthor(......);
BookaBook=newBook("Javafordummy",anAuthor,19.95,1000);
//UseananonymousinstanceofAuthor
BookanotherBook=newBook("moreJavafordummy",newAuthor(......),29.95,888);
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,
publicStringgetAuthorName(){......}
5/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
publicdoubledistance(MyPointanother){//thisversiontakesaMyPointinstanceasargument
intxDiff=this.xanother.x;
.......
}
//Testprogram
MyPointp1=newMyPoint(3,0);
MyPointp2=newMyPoint(0,4);
......
//Testingtheoverloadedmethoddistance()
System.out.println(p1.distance(p2));//whichversion?
System.out.println(p1.distance(5,6));//whichversion?
.....
2. 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 ten MyPoint instances.
MyPoint[]points=newMyPoint[10];//DeclareandallocateanarrayofMyPoint
for(......){
points[i]=newMyPoint(...);//AllocateeachofMyPointinstances
}
Notes: Point is such a common entity that JDK certainly provided for in all flavors.
6/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
class
called
MyTriangle,
which
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
7/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
isReal()
and
A method equals(double real, double imag) that returns true if this complex number is equal to the
given complex number of real, imag.
An overloaded equals(MyComplexanother) that returns true if this complex number is equal to the given
MyComplex instance another.
A method magnitudethat returns the magnitude of this complex number.
magnitude(x+yi)=Math.sqrt(x2+y2)
Methods argumentInRadians() and argumentInDegrees() that returns the argument of this complex
number in radians in double and degrees in int respectively.
arg(x+yi)=Math.atan2(y,x)(inradians)
Note: The Math library has two arctangent methods, Math.atan(double) and Math.atan2(double,
double). We commonly use the Math.atan2(y, x) instead of Math.atan(y/x) to avoid division by zero.
Read the documentation of Math class in package java.lang.
A method conjugate() that returns a new MyComplex instance containing the complex conjugate of this
instance.
conjugate(x+yi)=xyi
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
8/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
Hint:
returnnewMyComplex(real,imag);//constructanewinstanceandreturntheconstructedinstance
Methods add(MyComplex another) and subtract(MyComplex another) that adds and subtract this
instance with the given MyComplex instance another, and returns a new MyComplex instance containing the
result.
(a+bi)+(c+di)=(a+c)+(b+d)i
(a+bi)(c+di)=(ac)+(bd)i
Hint:
returnthis;//return"this"instance
Number1is:(1.1+2.2i)
(1.1+2.2i)isNOTapurerealnumber
(1.1+2.2i)isNOTapureimaginarynumber
Number2is:(3.3+4.4i)
(3.3+4.4i)isNOTapurerealnumber
(3.3+4.4i)isNOTapureimaginarynumber
(1.1+2.2i)isNOTequalto(3.3+4.4i)
(1.1+2.2i)+(3.3+4.4i)=(4.4+6.6000000000000005i)
(1.1+2.2i)(3.3+4.4i)=(2.1999999999999997+2.2i)
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 about 10^8 for comparing
floating point numbers.
The method add(), subtract(), and conjugate() produce new instances, whereas multiplyWith() and
divideBy() modify this instance. There is inconsistency in the design introduced for teaching purpose.
Unusual to have both argumentInRadians() and argumentInDegrees().
9/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
//Testprogram
//Caninvokewithavariablenumberofarguments
MyPolynomialp1=newMyPolynomial(1.1,2.2,3.3);
MyPolynomialp1=newMyPolynomial(1.1,2.2,3.3,4.4,5.5);
//Canalsoinvokewithanarray
Doublecoeffs={1.2,3.4,5.6,7.8}
MyPolynomialp2=newMyPolynomial(coeffs);
Another constructor that takes coefficients from a file of the given filename, having this format:
Degreen(int)
c0(double)
c1(double)
......
......
cn1(double)
cn(double)
(endoffile)
Hints:
publicMyPolynomial(Stringfilename){
Scannerin=null;
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
10/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
try{
in=newScanner(newFile(filename));//openfile
}catch(FileNotFoundExceptione){
e.printStackTrace();
}
intdegree=in.nextInt();//readthedegree
coeffs=newdouble[degree+1];//allocatethearray
for(inti=0;i<coeffs.length;++i){
coeffs[i]=in.nextDouble();
}
}
"11111111111111111111111111111111111111111111111111111111111111"
to
11/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
contains
the
following
public
methods:
setTime(int
hour,
int
it
shall
throw
an
12/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
in
the
isLeapYear(int
class
year):
returns
year,
intmonth,intday): 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(intyear): 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(intmonth): 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(intday): 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.
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
13/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
toString(): returns a date string in the format "xxxdaydmmmyyyy", e.g., "Tuesday 14 Feb 2012".
nextDay(): update this instance to the next day and return this instance. Take note that nextDay() for 31
Dec2000 shall be 1Jan2001.
nextMonth(): update this instance to the next month and return this instance. Take note that nextMonth()
for 31Oct2012 shall be 30Nov2012.
nextYear(): update this instance to the next year and return this instance. Take note that nextYear() for
29Feb2012 shall be 28Feb2013.
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:
MyDated1=newMyDate(2012,2,28);
System.out.println(d1);//Tuesday28Feb2012
System.out.println(d1.nextDay());//Wednesday29Feb2012
System.out.println(d1.nextDay());//Thursday1Mar2012
System.out.println(d1.nextMonth());//Sunday1Apr2012
System.out.println(d1.nextYear());//Monday1Apr2013
MyDated2=newMyDate(2012,1,2);
System.out.println(d2);//Monday2Jan2012
System.out.println(d2.previousDay());//Sunday1Jan2012
System.out.println(d2.previousDay());//Saturday31Dec2011
System.out.println(d2.previousMonth());//Wednesday30Nov2011
System.out.println(d2.previousYear());//Tuesday30Nov2010
MyDated3=newMyDate(2012,2,29);
System.out.println(d3.previousYear());//Monday28Feb2011
//MyDated4=newMyDate(2099,11,31);//Invalidyear,month,orday!
//MyDated5=newMyDate(2011,2,29);//Invalidyear,month,orday!
Write a test program that tests the nextDay() in a loop, by printing the dates from 28Dec2011 to 2Mar2012.
14/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
//DeclareandallocateanarrayofAuthors
Author[]authors=newAuthor[2];
authors[0]=newAuthor("TanAhTeck","[email protected]",'m');
authors[1]=newAuthor("PaulTan","[email protected]",'m');
//DeclareandallocateaBookinstance
BookjavaDummy=newBook("JavaforDummy",authors,19.99,99);
System.out.println(javaDummy);//toString()
System.out.print("Theauthorsare:");
javaDummy.printAuthors();
the
exercise,
above
the
number of authors
cannot be changed
once
instance
constructed.
Book
is
Suppose that we
wish to allow the
user to add more
authors which is
really unusual but
presented here for
academic purpose.
We shall remove
the authors from
the
and
constructors,
add a new
method
called
addAuthor()
to
add the given Author instance to this Book.
We also need to preallocate an Author array, with a fixed length says 5 a book is written by 1 to 5 authors, and
use another instance variable numAuthors int to keep track of the actual number of authors.
You are required to:
1. Modify your Book class to support this new requirement.
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
15/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
Hints:
publicclassBook{
//privateinstancevariable
privateAuthor[]authors=newAuthor[5];//declareandallocatethearray
//BUTnottheelement'sinstance
privateintnumAuthors=0;
......
......
publicvoidaddAuthor(Authorauthor){
authors[numAuthors]=author;
++numAuthors;
}
}
//Testprogram
BookjavaDummy=newBook("JavaforDummy",19.99,99);
System.out.println(javaDummy);//toString()
System.out.print("Theauthorsare:");
javaDummy.printAuthors();
javaDummy.addAuthor(newAuthor("TanAhTeck","[email protected]",'m'));
javaDummy.addAuthor(newAuthor("PaulTan","[email protected]",'m'));
System.out.println(javaDummy);//toString()
System.out.print("Theauthorsare:");
javaDummy.printAuthors();
2. Try writing a method called removeAuthorByName(authorName), that remove the author from this Book
instance if authorName is present. The method shall return true if it succeeds.
booleanremoveAuthorByName(StringauthorName)
Advanced Note: Instead of using a fixedlength array in this case, it is better to be a dynamically allocated array
e.g., ArrayList, which does not have a fixed length.
16/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
operations, the speed and direction are to be converted to (x,y) in the internal representation. Note
that the yaxis of the Java graphics coordinate system is inverted, i.e., the origin (0,0) is located at the top
left corner.
x=dcos()
y=dsin()
reflectHorizontal() which reflects the ball horizontally i.e., hitting a vertical wall
x=x
ynochanges
class
called
Container,
which
corners
of
the
rectangular box.
A constructor which accepts (x, y)
of the topleft corner, width and
height as argument, and converts
them into the internal representation i.e., x2=x1+width1. 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 "Containerat(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/or reflectVertical() to change the
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
17/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
2.Exercises on Inheritance
2.1Exercise: The Circle and Cylinder Classes
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
subclass Cylinder 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.
publicclassCylinderextendsCircle{//saveas"Cylinder.java"
privatedoubleheight;//privatevariable
//Constructorwithdefaultcolor,radiusandheight
publicCylinder(){
super();//callsuperclassnoargconstructorCircle()
height=1.0;
}
//Constructorwithdefaultradius,colorbutgivenheight
publicCylinder(doubleheight){
super();//callsuperclassnoargconstructorCircle()
this.height=height;
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
18/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
}
//Constructorwithdefaultcolor,butgivenradius,height
publicCylinder(doubleradius,doubleheight){
super(radius);//callsuperclassconstructorCircle(r)
this.height=height;
}
//Apublicmethodforretrievingtheheight
publicdoublegetHeight(){
returnheight;
}
//Apublicmethodforcomputingthevolumeofcylinder
//usesuperclassmethodgetArea()togetthebasearea
publicdoublegetVolume(){
returngetArea()*height;
}
}
Write a test program says TestCylinder to test the Cylinder class created, as follow:
publicclassTestCylinder{//saveas"TestCylinder.java"
publicstaticvoidmain(String[]args){
//Declareandallocateanewinstanceofcylinder
//withdefaultcolor,radius,andheight
Cylinderc1=newCylinder();
System.out.println("Cylinder:"
+"radius="+c1.getRadius()
+"height="+c1.getHeight()
+"basearea="+c1.getArea()
+"volume="+c1.getVolume());
//Declareandallocateanewinstanceofcylinder
//specifyingheight,withdefaultcolorandradius
Cylinderc2=newCylinder(10.0);
System.out.println("Cylinder:"
+"radius="+c2.getRadius()
+"height="+c2.getHeight()
+"basearea="+c2.getArea()
+"volume="+c2.getVolume());
//Declareandallocateanewinstanceofcylinder
//specifyingradiusandheight,withdefaultcolor
Cylinderc3=newCylinder(2.0,10.0);
System.out.println("Cylinder:"
+"radius="+c3.getRadius()
+"height="+c3.getHeight()
+"basearea="+c3.getArea()
+"volume="+c3.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
=2radiusheight + 2basearea 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
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
19/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
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
publicStringtoString(){//inCylinderclass
return"Cylinder:subclassof"+super.toString()//useCircle'stoString()
+"height="+height;
}
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
20/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
Write a superclass called Shape as shown in the class diagram, which contains:
Two instance variables color String and filled boolean.
Two constructors: a noarg noargument constructor that initializes the color to "green" and filled to
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
21/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
true, and a constructor that initializes the color and filled to the given values.
Getter and setter for all the instance variables. By convention, the getter for a boolean variable xxx is called
isXXX() instead of getXxx() for all the other types.
A toString() method that returns "AShapewithcolorofxxxandfilled/Notfilled".
Write a test program to test all the methods defined in Shape.
Write two subclasses of Shape called Circle and Rectangle, as shown in the class diagram.
The Circle class contains:
An instance variable radius double.
Three constructors as shown. The noarg constructor initializes the radius to 1.0.
Getter and setter for the instance variable radius.
Methods getArea() and getPerimeter().
Override the toString() method inherited, to return "ACirclewithradius=xxx,whichisasubclass
ofyyy", where yyy is the output of the toString() method from the superclass.
The Rectangle class contains:
Two instance variables width double and length double.
Three constructors as shown. The noarg constructor initializes the width and length to 1.0.
Getter and setter for all the instance variables.
Methods getArea() and getPerimeter().
Override the toString() method inherited, to return "A Rectangle with width=xxx and length=zzz,
whichisasubclassofyyy", where yyy is the output of the toString() method from the superclass.
Write a class called Square, as a subclass of Rectangle. Convince yourself that Square can be modeled as a
subclass of Rectangle. Square has no instance variable, but inherits the instance variables width and length from
its superclass Rectangle.
Provide the appropriate constructors as shown in the class diagram. Hint:
publicSquare(doubleside){
super(side,side);//CallsuperclassRectangle(double,double)
}
22/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
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 for Point and Line says
TestPoint and TestLine.
publicclassPoint{
//Privatevariables
privateintx;//xcoordinate
privateinty;//ycoordinate
//Constructor
publicPoint(intx,inty){......}
//Publicmethods
publicStringtoString(){
return"Point:("+x+","+y+")";
}
publicintgetX(){......}
publicintgetY(){......}
publicvoidsetX(intx){......}
publicvoidsetY(inty){......}
publicvoidsetXY(intx,inty){......}
}
publicclassTestPoint{
publicstaticvoidmain(String[]args){
Pointp1=newPoint(10,20);//ConstructaPoint
System.out.println(p1);
//Trysettingp1to(100,10).
......
}
}
publicclassLine{
//Alinecomposesoftwopoints(asinstancevariables)
privatePointbegin;//beginningpoint
privatePointend;//endingpoint
//Constructors
publicLine(Pointbegin,Pointend){//callertoconstructthePoints
this.begin=begin;
......
}
publicLine(intbeginX,intbeginY,intendX,intendY){
begin=newPoint(beginX,beginY);//constructthePointshere
......
}
//Publicmethods
publicStringtoString(){......}
publicPointgetBegin(){......}
publicPointgetEnd(){......}
publicvoidsetBegin(......){......}
publicvoidsetEnd(......){......}
publicintgetBeginX(){......}
publicintgetBeginY(){......}
publicintgetEndX(){......}
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
23/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
publicintgetEndY(){......}
publicvoidsetBeginX(......){......}
publicvoidsetBeginY(......){......}
publicvoidsetBeginXY(......){......}
publicvoidsetEndX(......){......}
publicvoidsetEndY(......){......}
publicvoidsetEndXY(......){......}
publicintgetLength(){......}//Lengthoftheline
//Math.sqrt(xDiff*xDiff+yDiff*yDiff)
publicdoublegetGradient(){......}//Gradientinradians
//Math.atan2(yDiff,xDiff)
}
publicclassTestLine{
publicstaticvoidmain(String[]args){
Linel1=newLine(0,0,3,4);
System.out.println(l1);
Pointp1=newPoint(...);
Pointp2=newPoint(...);
Linel2=newLine(p1,p2);
System.out.println(l2);
...
}
}
The class diagram for composition is as follows where a diamondhollowhead 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 redesign 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.
publicclassLineSubextendsPoint{
//Alineneedstwopoints:beginandend.
//ThebeginpointisinheritedfromitssuperclassPoint.
//Privatevariables
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
24/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
Pointend;//Endingpoint
//Constructors
publicLineSub(intbeginX,intbeginY,intendX,intendY){
super(beginX,beginY);//constructthebeginPoint
this.end=newPoint(endX,endY);//constructtheendPoint
}
publicLineSub(Pointbegin,Pointend){//callertoconstructthePoints
super(begin.getX(),begin.getY());//needtoreconstructthebeginPoint
this.end=end;
}
//Publicmethods
//InheritsmethodsgetX()andgetY()fromsuperclassPoint
publicStringtoString(){...}
publicPointgetBegin(){...}
publicPointgetEnd(){...}
publicvoidsetBegin(...){...}
publicvoidsetEnd(...){...}
publicintgetBeginX(){...}
publicintgetBeginY(){...}
publicintgetEndX(){...}
publicintgetEndY(){...}
publicvoidsetBeginX(...){...}
publicvoidsetBeginY(...){...}
publicvoidsetBeginXY(...){...}
publicvoidsetEndX(...){...}
publicvoidsetEndY(...){...}
publicvoidsetEndXY(...){...}
publicintgetLength(){...}//Lengthoftheline
publicdoublegetGradient(){...}//Gradientinradians
}
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 and LineSub designs: Line uses
composition and LineSub uses inheritance. Which design is better?
That
is,
"a
cylinder
is
//Constructorwithdefaultcolor,radiusandheight
publicCylinder(){
base=newCircle();//CalltheconstructortoconstructtheCircle
height=1.0;
}
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
25/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
......
}
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
26/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
27/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
The subclasses Circle and Rectangle shall override the abstract methods getArea() and getPerimeter() and
provide the proper implementation. They also override the toString().
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.
Shapes1=newCircle(5.5,"RED",false);//UpcastCircletoShape
System.out.println(s1);//whichversion?
System.out.println(s1.getArea());//whichversion?
System.out.println(s1.getPerimeter());//whichversion?
System.out.println(s1.getColor());
System.out.println(s1.isFilled());
System.out.println(s1.getRadius());
Circlec1=(Circle)s1;//DowncastbacktoCircle
System.out.println(c1);
System.out.println(c1.getArea());
System.out.println(c1.getPerimeter());
System.out.println(c1.getColor());
System.out.println(c1.isFilled());
System.out.println(c1.getRadius());
Shapes2=newShape();
Shapes3=newRectangle(1.0,2.0,"RED",false);//Upcast
System.out.println(s3);
System.out.println(s3.getArea());
System.out.println(s3.getPerimeter());
System.out.println(s3.getColor());
System.out.println(s3.getLength());
Rectangler1=(Rectangle)s3;//downcast
System.out.println(r1);
System.out.println(r1.getArea());
System.out.println(r1.getColor());
System.out.println(r1.getLength());
Shapes4=newSquare(6.6);//Upcast
System.out.println(s4);
System.out.println(s4.getArea());
System.out.println(s4.getColor());
System.out.println(s4.getSide());
//TakenotethatwedowncastShapes4toRectangle,
//whichisasuperclassofSquare,insteadofSquare
Rectangler2=(Rectangle)s4;
System.out.println(r2);
System.out.println(r2.getArea());
System.out.println(r2.getColor());
System.out.println(r2.getSide());
System.out.println(r2.getLength());
//DowncastRectangler2toSquare
Squaresq1=(Square)r2;
System.out.println(sq1);
System.out.println(sq1.getArea());
System.out.println(sq1.getColor());
System.out.println(sq1.getSide());
System.out.println(sq1.getLength());
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
28/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
4.2Exercise: Polymorphism
Examine the following codes and draw the class diagram.
abstractpublicclassAnimal{
abstractpublicvoidgreeting();
}
publicclassCatextendsAnimal{
@Override
publicvoidgreeting(){
System.out.println("Meow!");
}
}
publicclassDogextendsAnimal{
@Override
publicvoidgreeting(){
System.out.println("Woof!");
}
publicvoidgreeting(Doganother){
System.out.println("Woooooooooof!");
}
}
publicclassBigDogextendsDog{
@Override
publicvoidgreeting(){
System.out.println("Woow!");
}
@Override
publicvoidgreeting(Doganother){
System.out.println("Woooooowwwww!");
}
}
//UsingPolymorphism
Animalanimal1=newCat();
animal1.greeting();
Animalanimal2=newDog();
animal2.greeting();
Animalanimal3=newBigDog();
animal3.greeting();
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
29/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
Animalanimal4=newAnimal();
//Downcast
Dogdog2=(Dog)animal2;
BigDogbigDog2=(BigDog)animal3;
Dogdog3=(Dog)animal3;
Catcat2=(Cat)animal2;
dog2.greeting(dog3);
dog3.greeting(dog2);
dog2.greeting(bigDog2);
bigDog2.greeting(dog2);
bigDog2.greeting(bigDog1);
}
}
30/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
......
}
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.
publicclassMovablePointimplementsMovable{//savedas"MovablePoint.java"
//instancevariables
intx,y,xSpeed,ySpeed;//packageaccess
//Constructor
publicMovablePoint(intx,inty,intxSpeed,intySpeed){
this.x=x;
......
}
......
//ImplementabstractmethodsdeclaredintheinterfaceMovable
@Override
publicvoidmoveUp(){
y=ySpeed;//yaxispointingdownfor2Dgraphics
}
......
}
publicclassMovableCircleimplementsMovable{//savedas"MovableCircle.java"
//instancevariables
privateMovablePointcenter;//canusecenter.x,center.ydirectly
//becausetheyarepackageaccessible
privateintradius;
//Constructor
publicMovableCircle(intx,inty,intxSpeed,intySpeed,intradius){
//CalltheMovablePoint'sconstructortoallocatethecenterinstance.
center=newMovablePoint(x,y,xSpeed,ySpeed);
......
}
......
//ImplementabstractmethodsdeclaredintheinterfaceMovable
@Override
publicvoidmoveUp(){
center.y=center.ySpeed;
}
......
}
Movablem2=newMovableCircle(2,1,2,20);//upcast
System.out.println(m2);
m2.moveRight();
System.out.println(m2);
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
31/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
Write a new class called MovableRectangle, which composes two MovablePoints representing the topleft and
bottomright corners and implementing the Movable Interface. Make sure that the two points has the same speed.
1. Write the interface called GeometricObject, which declares two abstract methods: getParameter()
and getArea(), as specified in the class diagram.
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
32/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
Hints:
publicinterfaceGeometricObject{
publicdoublegetPerimeter();
......
}
2. Write the implementation class Circle, with a protected variable radius, which implements the interface
GeometricObject.
Hints:
publicclassCircleimplementsGeometricObject{
//Privatevariable
......
//Constructor
......
//ImplementmethodsdefinedintheinterfaceGeometricObject
@Override
publicdoublegetPerimeter(){......}
......
}
3. Write a test program called TestCircle to test the methods defined in Circle.
4. 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 an abstract method
resize(), which modifies the dimension such as radius by the given percentage. Write the interface
Resizable and the class ResizableCircle.
Hints:
publicinterfaceResizable{
publicdoubleresize(...);
}
publicclassResizableCircleextendsCircleimplementsResizeable{
//Constructor
publicResizableCircle(doubleradius){
super(...);
}
//ImplementmethodsdefinedintheinterfaceResizable
@Override
publicdoubleresize(intpercent){......}
}
5. Write a test program called TestResizableCircle to test the methods defined in ResizableCircle.
33/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
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.
segments
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 fixedlength, and you need to set the initial length.
publicclassPoint{
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
34/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
privateintx;
privateinty;
publicPoint(intx,inty){......}
publicStringtoString(){......}
}
importjava.util.*;
publicclassPolyLine{
privateList<Point>points=newArrayList<Point>();
//AllocateanArrayListofPointsandupcasttoList
publicPolyLine(){}//defaultconstructor
publicPolyLine(List<Point>points){
this.points=points;
}
//Appendapointat(x,y)totheendofthispolyline
publicvoidappendPoint(intx,inty){
PointnewPoint=newPoint(x,y);
points.add(newPoint);
}
//Appendapointinstancetotheendofthispolyline
publicvoidappendPoint(Pointpoint){
points.add(point);
}
//return(x1,y1)(x2,y2)(x3,y3)....
publicStringtoString(){
StringBuildersb=newStringBuilder();
for(PointaPoint:points){
sb.append(aPoint.toString());
}
returnsb.toString();
}
}
publicclassTestPolyLine{
publicstaticvoidmain(String[]args){
PolyLinel1=newPolyLine();
System.out.println(l1);//empty
l1.appendPoint(newPoint(1,1));
l1.appendPoint(2,2);
l1.appendPoint(3,3);
System.out.println(l1);//(1,1)(2,2)(3,3)
}
}
35/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
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
OOP_MyIntStack.java
publicclassMyIntStack{
privateint[]contents;
privateinttos;//Topofthestack
//constructors
publicMyIntStack(intcapacity){
contents=newint[capacity];
tos=1;
}
publicvoidpush(intelement){
contents[++tos]=element;
}
publicintpop(){
returncontents[tos];
}
publicintpeek(){
returncontents[tos];
}
publicbooleanisEmpty(){
returntos<0;
}
publicbooleanisFull(){
returntos==contents.length1;
}
}
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 sucessful, or false otherwise.
3. Modify the push() to increase the capacity by reallocating another array, if the stack is full.
Exercise Maps:
[TODO]
Representation of map data.
Specialized algorithms, such as shortest path.
36/37
18/4/2015
OOPExercisesJavaProgrammingTutorial
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.
Feedback, comments, corrections, and errata can be sent to Chua HockChuan ([email protected]) | HOME
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3f_OOPExercises.html
37/37