OOP Lab03 ObjectOrientedTechniques
OOP Lab03 ObjectOrientedTechniques
0. Assignment Submission
For this lab class, you will have to turn in your work twice, specifically:
▪ Right after the class: for this deadline, you should include any work you have done within the lab
class.
▪ A week before the next class: for this deadline, you should include the source code of all sections
of this lab. Additionally, for the reading assignment, submit a pdf file of the reading assignment in
the folder namely “ReadingAssignment”. After you finish all your work in the “master” branch,
please create a branch namely “release/lab03” of the valid repository to submit all your work.
Notice: After completing all the exercises in the lab, you have to update the use case diagram and the class
diagram of the AIMS project.
Each student is expected to turn in his or her own work and not give or receive unpermitted aid. Otherwise,
we would apply extreme methods for measurement to prevent cheating. Please write down answers for all
questions into a text file named “answers.txt” and submit it within your repository.
Page 1 of 23
1. Import the existing project into the workspace of Eclipse
- Step 1: Open Eclipse
- Step 2: Open File → Import. Type zip to find Archive File if you have exported as a zip file before.
You may choose Existing Projects into Workspace if you want to open an existing project in your
computer. Ignore this step if the AimsProject is already opened in the workspace.
- Video: https://www.youtube.com/watch?v=9gAjIQc4bPU&t=8s
Debugging is the routine process of locating and removing bugs, errors or abnormalities from
programs. It’s a must have skill for any Java developer because it helps to find subtle bugs that are not
visible during code reviews or that only happen when a specific condition occurs. The Eclipse Java IDE
provides many debugging tools and views grouped in the Debug Perspective to help you as a developer
debug effectively and efficiently.
Debug run allows you to run a program interactively while watching the source code and the
variables during the execution. A breakpoint in the source code specifies where the execution of the program
Page 2 of 23
should stop during debugging. Once the program is stopped you can investigate variables, change their
content, etc.
2.2. Example of debug run for the swap method of TestPassingParameter
2.2.1. Setting, deleting & deactivate breakpoints:
To set a breakpoint, place the cursor on the line that needs debugging, hold down Ctrl+Shift, and
press B to enable a breakpoint. A blue dot in front of the line will appear (Figure 2). Alternatively, you can
right-click in the left margin of the line in the Java editor and select Toggle Breakpoint. This is equivalent
to double-clicking in the left margin of the line.
To delete a breakpoint, toggle the breakpoint one more time. The blue dot in front of the line will
disappear (Figure 3).
Page 3 of 23
Figure 3 The breakpoint is deleted
To deactivate the breakpoint, navigate to the Breakpoints View and uncheck the tick mark next to
the breakpoint you want to deactivate (Figure 4). The program will only stop at activated breakpoints.
For this example, we will need to keep this breakpoint, so make sure to set the breakpoint again after
practicing with deleting/deactivating it before moving to the next section.
2.2.2. Run in Debug mode:
Select a Java file with a main method that contains the code that you need to debug from the Project
Explorer. In this example, we choose the TestPassingParameter.java file. Right click and choose Debug
As > Java Application (Figure 5).
Page 4 of 23
Figure 5. Run Debug from a class
Alternatively, you can select the project root node in the Project Explorer and click the debug icon in the
Eclipse toolbar (Figure 6)
The application will now be started with Eclipse attached as a debugger. Confirm to open the Debug
Perspective.
2.2.3. Step Into, Step Over, Step Return, Resume:
In the Debug Perspective, you can observe the Step Into/Over/Return & Resume/Terminate buttons
on the toolbar as in Figure 7.
Page 5 of 23
With debugger options, the difference between "Step into" and "Step over" is only noticeable if you
run into a function call:
○ "Step into" (F5) means that the debugger steps into the function
○ “Step over" (F6) just moves the debugger to the next line in the same Java action
With "Step Return" (pressing F7), you can instruct the debugger to leave the function; this is
basically the opposite of "Step into."
Clicking "Resume" (F8) instructs the debugger to continue until it reaches another breakpoint.
For this example, we need to see the execution of the swap function, so we choose Step Into. The debugger
will step into the implementation of the swap function in line 18 (Figure 8).
Page 6 of 23
Figure 9. Variables shown in Variable View
Click Step Over and watch the change in the value of variables o1, o2 & tmp. Repeat this until
the end of the swap function (Figure 10, Figure 11, Figure 12).
Page 7 of 23
Figure 11. Step over line 19 of swap function
Page 8 of 23
Figure 13. Step return to main function
The variable jungleDVD still has a title attribute with value “Jungle”. You can change this value
by clicking on it and change it to “abc”, for example (Figure 14).
Click Step Over and see the result in the output in the Console (Figure 15)
Page 9 of 23
3. Re-organize your project
- Rename project, use packages and reorganize all hands-on labs and exercises from the Lab01 up to
now.
○ For renaming or moving an item (i.e. a project, a class, a variable…), right click to the item,
choose Refactor -> Rename/Move and follow the steps.
○ For creating a package, right click to the project (or go to menu File) and choose New ->
Package. Type the full path of the package including parent packages, separated by a dot.
- Keep the text file for answering questions in the lab, the “Requirement”, “Design” and “Reading
Assignment” folders should be moved inside the root folder of AimsProject, next to its src/ and
bin/ folder.
- Your structure of your labs should be at least as below. You can create sub-packages for more
efficiently organizing your classes in both projects and all listing packages. All the exercises of lab01
should be put in the corresponding package of one project - the OtherProjects project.
- This is an example of how to refactor your project's folder structure if you are a DS-AI student.
+ AimsProject
hust.soict.dsai.aims.disc.DigitalVideoDisc
hust.soict.dsai.aims.cart.Cart
hust.soict.dsai.aims.Aims
hust.soict.dsai.test.cart.CartTest
hust.soict.dsai.test.disc.TestPassingParameter
+ OtherProjects
hust.soict.dsai.lab01
hust.soict.dsai.lab02
hust.soict.dsai.lab03
Page 10 of 23
Figure 17. Recommended Structure for DS-AI
Notice: From this section onwards, it is assumed that you are a DS-AI student, so your folder structure will
contain the “dsai” package. If you are an HEDSPI or ICT student, you should replace the “dsai” string
with “hedspi” or “globalict”.
Page 11 of 23
Figure 18. Code snippet for CartTest
Page 12 of 23
Figure 19. ConcatenationInLoops
Notice: For more information on String concatenation, please access this link:
https://redfin.engineering/java-string-concatenation-which-way-is-best-8f590a7d22a8.
- Create a new class GarbageCreator. Create “garbage” as much as possible and observe when
you run a program (it should let the program hang or even stop working when there is too much
“garbage”). Write another class NoGarbage to solve the problem.
Some suggestions:
- Read a text/binary file to a String without using StringBuffer to concatenate String (only
use + operator). Observe and capture your screen when you choose a very long file
- Improve the code using StringBuffer.
The following piece of code is a suggestion for your implementation
Change the code in line 14-17 above to use StringBuffer instead of “+” operator to build string and
observe result
Page 13 of 23
Figure 21. New code using StringBuffet
Page 14 of 23
Figure 22. Adding fields to Book class
○ Instead of typing the accessor methods for these fields, you may use the Generate Getter
and Setter option in the Outline view pop-up menu (i.e., Right Click -> Source ->
Generate Getters and Setters...). Note that in reality, not all attributes need to have getter
and setter. We only create this when necessary. Getter and setter generator of Eclipse also
let you decide which attribute will get getter or setter or both.
○ Next, create addAuthor(String authorName) and removeAuthor(String
authorName) for the Book class
○ The addAuthor(...) method should ensure that the author is not already in the
ArrayList before adding
○ The removeAuthor(...) method should ensure that the author is present in the
ArrayList before removing
○ Reference to some useful methods of the ArrayList class
Page 15 of 23
o To store the information common to the DigitalVideoDisc and the Book classes, the
Media class requires four private fields: int id, String title, String category
and float cost
o You will want to make public accessor methods for these fields (by using Generate Getter
and Setter option in the Outline view pop-up menu)
- Remove fields and methods from Book and DigitalVideoDisc classes
o Open the Book.java in the editor
o Locate the Outline view on the right-hand side
o Select the fields id, title, category, cost and their accessors & mutators (if exist)
o Right click the selection and select Delete from the pop-up menu
o Save your changes
- Do similarly for the DigitalVideoDisc class and move it to the package
hust.soict.dsai.aims.media. Remove the package
hust.soict.dsai.aims.disc.
After doing that you will see a lot of errors because of the missing fields
Extend the Media class for both Book and DigitalVideoDisc
public class Book extends Media
public class DigitalVideoDisc extends Media
Save your changes.
Page 16 of 23
● an ArrayList of Track as tracks
- Make all these fields private. Create a public getter method for only
artists.
- Create constructor(s) for this class. Use super() if possible.
- Create methods addTrack() and removeTrack()
● The addTrack() method should check if the input track is already in the list
of tracks and inform users
● The removeTrack() method should check if the input track existed in the
list of tracks and inform users
- Create the getLength() method
● Because each track in the CD has a length, the length of the CD should be the
sum of lengths of all its tracks.
- Save your changes
11. Implementation of the Playable interface
The Playable interface is created to allow classes to indicate that they implement a play() method.
You can apply Release Flow here by creating a topic branch for implementing Playable interface.
- Create Playable interface, and add to it the method prototype: public void play();
- Save your changes
- Implement the Playable with CompactDisc, DigitalVideoDisc and Track
○ For each of these classes CompactDisc and DigitalVideoDisc, edit the class
description to include the keywords implements Playable, after the keyword
extends Disc
○ For the Track class, insert the keywords implements Playable after the keywords
public class Track
- Implement play() for DigitalVideoDisc and Track
○ Add the method play() to these two classes
○ In the DigitalVideoDisc, simply print to screen:
public void play() {
System.out.println("Playing DVD: " + this.getTitle());
System.out.println("DVD length: " + this.getLength());
}
○ Similar additions with the Track class
- Implement play() method for CompactDisc
○ Since the CompactDisc class contains an ArrayList of Tracks, each of which can
be played on its own. The play() method should output some information about the
CompactDisc to console
○ Loop through each track of the arraylist and call Track's play() method
Page 17 of 23
12. Update the Cart class to work with Media
You must now update the Cart class to accept not only DigitalVideoDisc but also Book and
CompactDisc. Currently, the Cart class has methods:
● addDigitalVideoDisc()
● removeDigitalVideoDisc().
You could add more methods to add and remove Book and CompactDisc, but since
DigitalVideoDisc, Book and CompactDisc are all subclasses of type Media, you can simply
change Cart to maintain a collection of Media objects. Thus, you can add a DigitalVideoDisc, or
a Book, or a CompactDisc using the same methods.
- Remove the itemsOrdered array, as well as its add and remove methods:
○ Step 1: From the Package Explorer view, expand the project
○ Step 2: Double-click Cart.java to open it in the editor
○ Step 3: In the Outline view, select the itemsOrdered array and the methods
addDigitalVideoDisc() and removeDigitalVideoDisc() and hit the Delete
key
○ Step 4: Click Yes when prompted to confirm the deletion
○ Step 5: Recreate the itemsOrdered field, this time as an object ArrayList instead of
an array.
■ The qtyOrdered field is no longer needed since it was used to track the number
of DigitalVideoDiscs in the itemsOrdered array, so remove it and its
accessor and mutator (if exist).
■ Add the itemsOrdered to the Cart class
○ Step 6: To create this field, type the following code in the Cart class, in place of the
itemsOrdered array declaration that you deleted:
private ArrayList<Media> itemsOrdered = new ArrayList<Media>();
- Note that you should import the java.util.ArrayList in the Cart class
Notice: A quicker way to achieve the same effect is to use the Organize Imports feature within
Eclipse:
● Right-click anywhere in the editor for the Cart class and select Source -> Organize Imports
(Or Ctrl+Shift+O). This will insert the appropriate import statements in your code.
● Save your class
- Create addMedia() and removeMedia() to replace addDigitalVideoDisc() and
removeDigitalVideoDisc()
- Update the totalCost() method
13. Update the Store class to work with Media
- Similar to the Cart class, change the itemsInStore[] attribute of the Store class to
ArrayList<Media> type.
- Replace the addDigitalVideoDisc() and removeDigitalVideoDisc() methods with
addMedia() and removeMedia()
Page 18 of 23
14. Constructors of whole classes and parent classes
- Write constructors for parent and child classes. Remove redundant setter methods if any
- Which classes are aggregates of other classes? Checking all constructors of whole classes if they
initialize for their parts?
15. Unique item in a list
To make sure the list of media in cart or list of tracks in a CD should not contain identical objects, we can
override the equals() method of the Object class
Previously, when you add a media to a cart or a track to a CD, you may use the contains() methods
of the list of medias in the cart or the list of tracks in the CD to ensure that a similar object is not added to
that list.
When calling this by default, contains() will check a variety of conditions in order to confirm that 2
tracks are identical. However, you can define your own requirements to perform the verification.
The contains() method returns true if the list contains the specific element. More formally, it returns
true if and only if the list contains at least one element e such that e such that
(o==null?e==null:o.equals(e)). So the contains() method actually uses equals()
method to check equality.
- Please override the boolean equals(Object o) of the Media and the Track class so
that two objects of these classes can be considered as equal if:
○ For the Media class: the title is equal
○ For the Track class: the title and the length are equal
- When overriding the equals() method of the Object class, you will have to cast the Object
parameter obj to the type of Object that you are dealing with. For example, in the Media class,
you must cast the Object obj to a Media, and then check the equality of the two objects’ attributes
as the above requirements (i.e. title for Media; title and length for Track). If the
passing object is not an instance of Media, what happens?
Notice: We can apply Release Flow here by creating a topic branch for the override of equals()
method.
Page 19 of 23
Figure 23. Polymorphism sample code
Note: The Comparator interface is a comparison function, which imposes a total ordering on some
collection of objects. Comparators can be passed to a sort method (such as Collections.sort())
to allow precise control over the sort order.
Please open the Java docs to see the information of this interface.
- Create two classes of comparators, one for each type of ordering
- Implement the compare() method of each comparator class to reflect the ordering that we want,
either by title then cost, or by cost then title. You may utilize the method
Comparator.thenComparing()to sort using multiple fields.
- Add the comparators as attributes of the Media class:
Page 20 of 23
- Pass the comparator into Collections.sort:
java.util.Collection.sort(collection,Media.COMPARE_BY_TITLE_C
OST)
or
java.util.Collection.sort(collection, Media.COMPARE_BY_COST_TITLE)
Question: Alternatively, to compare items in the cart, instead of using the Comparator class I have
mentioned, you can use the Comparable interface1 and override the compareTo()method. You can
refer to the Java docs to see the information of this interface.
Suppose we are taking this Comparable interface approach.
- What class should implement the Comparable interface?
- In those classes, how should you implement the compareTo()method to reflect the ordering that
we want?
- Can we have two ordering rules of the item (by title then cost and by cost then title) if we use this
Comparable interface approach?
- Suppose the DVDs have a different ordering rule from the other media types, that is by title, then
decreasing length, then cost. How would you modify your code to allow this?
1
Comparable (Java Platform SE 8 ) (oracle.com)
Page 21 of 23
public static void storeMenu() {
System.out.println("Options: ");
System.out.println("--------------------------------");
System.out.println("1. See a media’s details");
System.out.println("2. Add a media to cart");
System.out.println("3. Play a media");
System.out.println("4. See current cart");
System.out.println("0. Back");
System.out.println("--------------------------------");
System.out.println("Please choose a number: 0-1-2-3-4");
}
o The option “See a media’s details” will ask the user to enter the title of the media and
display the information of that media. Please remember to check the validity of the title.
Under the information display, the system also shows the following menu (note that the
“Play” option is only available to CD and DVD type.
public static void mediaDetailsMenu() {
System.out.println("Options: ");
System.out.println("--------------------------------");
System.out.println("1. Add to cart");
System.out.println("2. Play");
System.out.println("0. Back");
System.out.println("--------------------------------");
System.out.println("Please choose a number: 0-1-2");
}
o The option “Add a media to cart” will ask the user to enter the title of the media that
he/she sees on the screen (the list of media in store), then add the media to cart. Please
remember to check the validity of the title. After adding a DVD to the cart, the system
will display the number of DVDs in the current cart.
o The option “Play a media” will ask the same input from the user as option 2. You should
again check the validity of the title.
● From the main menu, if the user chooses option “Update store”, the application will allow the
user to add a media to or remove a media from the store
● From the main menu, if the user chooses option “See current cart”, the application will display
the information of the current cart, and a menu as following:
public static void cartMenu() {
System.out.println("Options: ");
System.out.println("--------------------------------");
System.out.println("1. Filter media in cart");
System.out.println("2. Sort media in cart");
System.out.println("3. Remove media from cart");
System.out.println("4. Play a media");
System.out.println("5. Place order");
System.out.println("0. Back");
System.out.println("--------------------------------");
System.out.println("Please choose a number: 0-1-2-3-4-5");
Page 22 of 23
}
o The “Filter media in cart” option should allow the user to choose one of two
filtering options: by id and by title.
o The “Sort media in cart” option should allow the user to choose one of two sorting
options: by title or by cost.
Note: When the user chooses option “Place order”, the system is supposed to move on to the
Delivery Information gathering & Payment step. However, for simplicity, within the scope of
this lab course, when the user chooses this option, we only need to notify the user that an order
is created and empty the current cart.
• Update the UML class diagram for the AimsProject. Update the new .astah & .png file in the
Design directory. We can apply Release Flow here by creating a branch, e.g., topic/update-
class-diagram/aims-project/lab03, push the diagram and its image, and then merge
with master
Page 23 of 23