Composition
Objective
- Composition and its practical applications in software development.
- Build a complete example using object-oriented programming with composition.
Exercise 1*
Customer Class
A class can have references to objects of other classes as members. This is called composition and is sometimes referred to as a has-a relationship. For example, a Customer
object needs to record the Address
of the client. The address is not a simple string, it is another object with many fields.
-
Add the following
Customer
andAddress
classes to your project:Customer.javapublic class Customer { private String name; private String phone; private int id; public Customer(String name, String phone, int id) { this.name = name; this.phone = phone; this.id = id; } public String getName() { return name; } public String getPhone() { return phone; } public int getId() { return id; } public void setName(String name) { this.name = name; } public void setPhone(String phone) { this.phone = phone; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Name: " + name + ", Phone: " + phone + ", ID: " + id; } }
Address.javapublic class Address { private String street; private String city; private String state; private String zip; public Address(String street, String city, String state, String zip) { this.street = street; this.city = city; this.state = state; this.zip = zip; } public String getStreet() { return street; } public String getCity() { return city; } public String getState() { return state; } public String getZip() { return zip; } public void setStreet(String street) { this.street = street; } public void setCity(String city) { this.city = city; } public void setState(String state) { this.state = state; } public void setZip(String zip) { this.zip = zip; } @Override public String toString() { return street + ", " + city + ", " + state + " " + zip; } }
-
Modify the class
Customer
by adding new data member calledaddress
of typeAddress
. -
Add a fully parameterized constructor in the
Customer
class that initializes all fields including theaddress
. -
Add a setter and a getter for the
address
data member.
- Modify the
toString()
method by adding theAddress.toString()
to the returned string. - Create two
Customer
objects and set their addresses. - Test your code.
Exercise 2
Book Class
-
Add the following
Book
andAuthor
classes to your project:Book.javapublic class Book { private String isbn; private String title; private double price; public Book(String isbn, String title, double price) { this.isbn = isbn; this.title = title; this.price = price; } public String getIsbn() { return isbn; } public String getTitle() { return title; } public double getPrice() { return price; } public void setIsbn(String isbn) { this.isbn = isbn; } public void setTitle(String title) { this.title = title; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return title + " [" + isbn + "]" + " $" + price; } }
Author.javapublic class Author { private int id; private String firstName; private String lastName; public Author(int id, String firstName, String lastName) { this.id = id; this.firstName = firstName; this.lastName = lastName; } public int getId() { return id; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public void setId(int id) { this.id = id; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setLastName(String lastName) { this.lastName = lastName; } @Override public String toString() { return lastName + ", " + firstName; } }
-
Add an
author
with typeAuthor
as a new data member to theBook
class. -
Add a new
Book
constructor. -
Add a getter and a setter for
author
.
-
Use
Author
’stoString()
method inBook
’stoString()
method. -
Test your code.
-
Add the following
Publisher
class to your project:Publisher.javapublic class Publisher { private int id; private String name; private String email; public Publisher(int id, String name, String email) { this.id = id; this.name = name; this.email = email; } public int getId() { return id; } public String getName() { return name; } public String getEmail() { return email; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return name + "<" + email + ">"; } }
-
Add an
address
with typeAddress
as a new data member of thePublisher
class. -
Add a new constructor to the
Publisher
class. -
Define a getter and a setter for
address
. -
Use
Address
’stoString()
method inPublisher
’stoString()
method. -
Test your code.
-
Update the
Book
class by adding a new data memberpublisher
of typePublisher
. Repeat all the steps that you did previously with the other classes. -
Test your code with proper data.
Exercise 3
A book generally contains multiple chapters. Each chapter has a name and number of pages. We will make this change to the Book
class.
This time we are not going to add Chapter
as a data member but instead we will add an ArrayList
of Chapter
objects.
-
Add the following
Chapter
class to your project:Chapter.javapublic class Chapter { private String title; private int pageCount; public Chapter(String title, int pageCount) { this.title = title; this.pageCount = pageCount; } public String getTitle() { return title; } public int getPageCount() { return pageCount; } public void setTitle(String title) { this.title = title; } public void setPageCount(int pageCount) { this.pageCount = pageCount; } @Override public String toString() { return title + " (" + pageCount + " pages)"; } }
-
Add an
ArrayList
ofChapter
s namedchapters
as a new data member. There is no need to create or modify the constructor. -
Add a setter and getter for
chapters
. -
Add two methods:
void addChapter(Chapter c)
andvoid removeChapter(Chapter c)
. Theadd()
andremove()
methods will make the changes directly to the list of chapters. -
Add a two methods:
int getPageCount()
, that returns the total number of pages in all the chapters, andint getChapterCount()
. -
Modify the
toString()
method of theBook
class to display the number of chapters and the total number of pages. -
Test your code with proper data. Create a
Book
object that has two chapters, a publisher who has an address, and an author:Address address = new Address("501 Boylston St.", "Boston", "Massachusetts", "02116"); Publisher publisher = new Publisher(1, "Addison-Wesley Professional", "[email protected]"); Author author = new Author(1, "Donald", "Knuth"); Chapter ch1 = new Chapter("Chapter 1: Basic concepts", 229); Chapter ch2 = new Chapter("Chapter 2: Information Structures", 234); Book book = new Book("978-0201896831", "The Art of Computer Programming, Vol. 1: Fundamental Algorithms", 62.49);
Modify the code above and associated classes so that your output is as follows:
The Art of Computer Programming, Vol. 1: Fundamental Algorithms by Knuth, Donald Publisher: Addison-Wesley Professional <[email protected]m>; 501 Boylston St., Boston, Massachusetts 02116 2 chapters, 463 pages, $62.49, [978-0201896831]
-
To support multiple authors for a single book, change the
author
data member to aList
ofAuthor
s and update the constructor. You also need to add methods likeint getAuthorCount()
,void addAuthor(Author a)
, andvoid removeAuthor(Author a)
.Make sure you do not add duplicate authors for a single book by preventing an author ID from being added twice. Furthermore, you need to print the list of all authors in the
toString()
of theBook
class.
Exercise 4+
Hotel Application
We are going to build a mini-hotel application. The hotel has a name, a location, and a list of rooms. Rooms can be booked and released. Three types of rooms available: single, double, and suite.
-
Add the following
Location
class to your project:Location.javapublic class Location { private String city; private String country; public Location(String city, String country) { this.city = city; this.country = country; } public String getCity() { return city; } public String getCountry() { return country; } public void setCity(String city) { this.city = city; } public void setCountry(String country) { this.country = country; } @Override public String toString() { return city + ", " + country; } }
-
Add the following
Room
class to your project:Room.javapublic class Room { private int number; private int floor; private boolean available; public Room(int number, int floor, boolean available) { this.number = number; this.floor = floor; this.available = available; } public int getNumber() { return number; } public int getFloor() { return floor; } public boolean isAvailable() { return available; } public void setNumber(int number) { this.number = number; } public void setFloor(int floor) { this.floor = floor; } public void setAvailable(boolean available) { this.available = available; } @Override public String toString() { return String.format("Room number: %d\tFloor: %d\tAvailable: %s", number, floor, (this.isAvailable() ? "Yes" : "No")); } }
-
Create a
RoomType
enumeration with three values:SINGLE
,DOUBLE
,SUITE
. -
Make
roomType
:RoomType
a field of theRoom
class. Add it to the fully parameterized constructor. -
Add a setter and getter for the
roomType
data member. -
Modify the
toString()
method of theRoom
class based on the following example:Room room = new Room(425,4, true, RoomType.DOUBLE); System.out.println(room);
[DOUBLE] Room number: 425 Floor: 4 Available: Yes
Composing Classes
The Hotel
class has three fields: name
, location
, and rooms
.
-
Provide two constructors: one takes the
name
, and the other takes thename
andlocation
. -
Provide setters and getters for all three fields.
-
Add three private constants to the
Hotel
class:private final double SINGLE_ROOM_RATE = 355.5; private final double DOUBLE_ROOM_RATE = 515.5; private final double SUITE_RATE = 1079.5;
-
Provide all the following methods:
public double getRoomRate(RoomType type)
: returns the rate for a given room type.public void addRoom(Room r)
: adds a new object to the hotel’s list of rooms.public void reserveRoom(int roomNumber)
: sets the room availability tofalse
.public void releaseRoom(int roomNumber)
: sets the room availability totrue
.public boolean isRoomAvailable(int roomNumber)
: returns room availability.public ArrayList<Room> getAvailableRooms()
: returns a list of the available rooms.public int getAvailableRoomsCount()
: returns the number of available rooms in the hotel’s list of rooms.public int getRoomsCount()
: returns the number of all hotel rooms.public ArrayList<Room> roomsInFloor(int floorNumber)
: returns a list of the rooms in a specific floor number.
-
Provide a
toString()
method that reuses code from all the included classes and generates a string based on the following output:Hotel: Hilton. Address: Doha, Qatar Room Count: 4 (Available: 3) Today's Income: $515.50 [DOUBLE] Room number: 425 Floor: 4 Available: No @ $515.50 [SINGLE] Room number: 423 Floor: 4 Available: Yes @ $355.50 [DOUBLE] Room number: 328 Floor: 3 Available: Yes @ $515.50 [SUITE] Room number: 218 Floor: 2 Available: Yes @ $1,079.50
Hotel Tester
-
Test your classes using the following code:
Hotel hotel = new Hotel("Hilton"); Room room1 = new Room(425, 4, true, RoomType.DOUBLE); Room room2 = new Room(423, 4, true, RoomType.SINGLE); Room room3 = new Room(328, 3, true, RoomType.DOUBLE); Room room4 = new Room(218, 2, true, RoomType.SUITE); hotel.setLocation(new Location("Doha", "Qatar")); hotel.addRoom(room1); hotel.addRoom(room2); hotel.addRoom(room3); hotel.addRoom(room4); hotel.reserveRoom(425); hotel.reserveRoom(218); System.out.println(hotel);
Booking Application
- Create a class named
BookingApplication
. - The
BookingApplication
class has two fields: a name and a list of hotels. - Discuss the usage of this application:
- What can you do with it?
- How can you benefit from the available code?
- What changes are needed to make it a fully-fledged application?