7 Composition

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.

  1. Add the following Customer and Address classes to your project:

    Customer.java
    public 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.java
    public 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;
      }
    }
  2. Modify the class Customer by adding new data member called address of type Address.

  3. Add a fully parameterized constructor in the Customer class that initializes all fields including the address.

  4. Add a setter and a getter for the address data member.

    Customer-name : String-phone : String-id : int-address : Address+Customer(String, String, int)+Customer(String, String, int, Address)+getName() : String+getPhone() : String+getId() : int+getAddress() : Address+setName(String) : void+setPhone(String) : void+setId(int) : void+setAddress(Address) : void+toString() : StringAddress-street : String-city : String-state : String-zip : String+Address(String, String, String, String)+getStreet() : String+getCity() : String+getState() : String+getZip() : String+setStreet(String) : void+setCity(String) : void+setState(String) : void+setZip(String) : void+toString() : String
  1. Modify the toString() method by adding the Address.toString() to the returned string.
  2. Create two Customer objects and set their addresses.
  3. Test your code.
Solution
Customer.java
public class Customer {
  private String name;
  private String phone;
  private int id;
  private Address address;
 
  public Customer(String name, String phone, int id) {
    this.name = name;
    this.phone = phone;
    this.id = id;
  }
 
  public Customer(String name, String phone, int id, Address address) {
    this.name = name;
    this.phone = phone;
    this.id = id;
    this.address = address;
  }
 
  public String getName() { return name; }
  public String getPhone() { return phone; }
  public int getId() { return id; }
  public Address getAddress() { return address; }
 
  public void setName(String name) { this.name = name; }
  public void setPhone(String phone) { this.phone = phone; }
  public void setId(int id) { this.id = id; }
  public void setAddress(Address address) { this.address = address; }
 
  @Override
  public String toString() {
    return "Name: " + name + ", Phone: " + phone + ", ID: " + id +
           ", Address: " + address;
  }
}
CustomerTest.java
public class CustomerTest {
  public static void main(String[] args) {
    Address address1 = new Address("123 Main St", "New York", "NY", "10001");
    Address address2 = new Address("456 Oak Ave", "Boston", "MA", "02115");
 
    Customer customer1 = new Customer("John Doe", "555-1234", 1001);
    customer1.setAddress(address1);
 
    Customer customer2 = new Customer("Jane Smith", "555-5678", 1002, address2);
 
    System.out.println(customer1);
    System.out.println(customer2);
  }
}

Exercise 2

Book Class

  1. Add the following Book and Author classes to your project:

    Book.java
    public 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.java
    public 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;
      }
    }
  2. Add an author with type Author as a new data member to the Book class.

  3. Add a new Book constructor.

  4. Add a getter and a setter for author.

    Book-isbn : String-title : String-price : double-author : Author+Book(String, String, double)+Book(String, String, double, Author)+getIsbn() : String+getTitle() : String+getPrice() : double+getAuthor() : Author+setIsbn(String) : void+setTitle(String) : void+setPrice(double) : void+setAuthor(Author) : void+toString() : StringAuthor-id : int-firstName : String-lastName : String+Author(int, String, String)+getId() : int+getFirstName() : String+getLastName() : String+setId(int) : void+setFirstName(String) : void+setLastName(String) : void+toString() : String
  1. Use Author’s toString() method in Book’s toString() method.

  2. Test your code.

  3. Add the following Publisher class to your project:

    Publisher.java
    public 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 + ">";
      }
    }
  4. Add an address with type Address as a new data member of the Publisher class.

  5. Add a new constructor to the Publisher class.

  6. Define a getter and a setter for address.

    Publisher-id : int-name : String-email : String-address : Address+Publisher(int, String, String)+Publisher(int, String, String, Address)+getId() : int+getName() : String+getEmail() : String+getAddress() : Address+setId(int) : void+setName(String) : void+setEmail(String) : void+setAddress(Address) : void+toString() : StringAddress
  7. Use Address’s toString() method in Publisher’s toString() method.

  8. Test your code.

  9. Update the Book class by adding a new data member publisher of type Publisher. Repeat all the steps that you did previously with the other classes.

    Book-author : Author-publisher : Publisher+Book(String, String, double, Author, Publisher)AuthorPublisher
  10. Test your code with proper data.

CustomerAddressBookAuthorPublisher
Solution
Book.java
public class Book {
  private String isbn;
  private String title;
  private double price;
  private Author author;
  private Publisher publisher;
 
  public Book(String isbn, String title, double price) {
    this.isbn = isbn;
    this.title = title;
    this.price = price;
  }
 
  public Book(String isbn, String title, double price, Author author) {
    this.isbn = isbn;
    this.title = title;
    this.price = price;
    this.author = author;
  }
 
  public Book(String isbn, String title, double price, Author author,
              Publisher publisher) {
    this.isbn = isbn;
    this.title = title;
    this.price = price;
    this.author = author;
    this.publisher = publisher;
  }
 
  public String getIsbn() { return isbn; }
  public String getTitle() { return title; }
  public double getPrice() { return price; }
  public Author getAuthor() { return author; }
  public Publisher getPublisher() { return publisher; }
 
  public void setIsbn(String isbn) { this.isbn = isbn; }
  public void setTitle(String title) { this.title = title; }
  public void setPrice(double price) { this.price = price; }
  public void setAuthor(Author author) { this.author = author; }
  public void setPublisher(Publisher publisher) { this.publisher = publisher; }
 
  @Override
  public String toString() {
    return title + " [" + isbn + "]" + " $" + price +
           (author != null ? " by " + author : "") +
           (publisher != null ? ", Publisher: " + publisher : "");
  }
}
Publisher.java
public class Publisher {
  private int id;
  private String name;
  private String email;
  private Address address;
 
  public Publisher(int id, String name, String email) {
    this.id = id;
    this.name = name;
    this.email = email;
  }
 
  public Publisher(int id, String name, String email, Address address) {
    this.id = id;
    this.name = name;
    this.email = email;
    this.address = address;
  }
 
  public int getId() { return id; }
  public String getName() { return name; }
  public String getEmail() { return email; }
  public Address getAddress() { return address; }
 
  public void setId(int id) { this.id = id; }
  public void setName(String name) { this.name = name; }
  public void setEmail(String email) { this.email = email; }
  public void setAddress(Address address) { this.address = address; }
 
  @Override
  public String toString() {
    return name + " <" + email + ">" + (address != null ? "; " + address : "");
  }
}
BookTest.java
public class BookTest {
  public static void main(String[] args) {
    Address address = new Address("501 Boylston St.", "Boston", "Massachusetts",
                                   "02116");
 
    Publisher publisher = new Publisher(1, "Addison-Wesley Professional",
                                        "[email protected]", address);
 
    Author author = new Author(1, "Donald", "Knuth");
 
    Book book = new Book("978-0201896831",
                         "The Art of Computer Programming, Vol. 1: "
                             + "Fundamental Algorithms",
                         62.49, author, publisher);
 
    System.out.println(book);
  }
}

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 a List of Chapter objects.

  1. Add the following Chapter class to your project:

    Chapter.java
    public 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)";
      }
    }
  2. Add a List of Chapters named chapters as a new data member. There is no need to create or modify the constructor.

  3. Add a setter and getter for chapters.

  4. Add two methods: void addChapter(Chapter c) and void removeChapter(Chapter c). The add() and remove() methods will make the changes directly to the list of chapters.

  5. Add a two methods: int getPageCount(), that returns the total number of pages in all the chapters, and int getChapterCount().

    Book-chapters : List<Chapter>+Book(String, String, double, Author, Publisher)+getChapters() : List<Chapter>+setChapters(List<Chapter>) : void+addChapter(Chapter) : void+removeChapter(Chapter) : void+getPageCount() : int+getChapterCount() : intChapter-title : String-pageCount : int+Chapter(String, int)+getTitle() : String+getPageCount() : String+setTitle(String) : void+setPageCount(int) : void+toString() : String
  6. Modify the toString() method of the Book class to display the number of chapters and the total number of pages.

  7. 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]
  8. To support multiple authors for a single book, change the author data member to a List of Authors and update the constructor. You also need to add methods like int getAuthorCount(), void addAuthor(Author a), and void 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 the Book class.

    Book-author : List<Author>+Book(String, String, double, Publisher)+getAuthors() : List<Author>+setAuthors(List<Author>) : void+getAuthorCount() : int+addAuthor(Author) : void+removeAuthor(Author) : voidAuthor
Solution
Book.java
import java.util.ArrayList;
import java.util.List;
 
public class Book {
  private String isbn;
  private String title;
  private double price;
  private List<Author> authors;
  private Publisher publisher;
  private List<Chapter> chapters;
 
  public Book(String isbn, String title, double price) {
    this.isbn = isbn;
    this.title = title;
    this.price = price;
    this.authors = new ArrayList<Author>();
    this.chapters = new ArrayList<Chapter>();
  }
 
  public Book(String isbn, String title, double price, Publisher publisher) {
    this.isbn = isbn;
    this.title = title;
    this.price = price;
    this.publisher = publisher;
    this.authors = new ArrayList<Author>();
    this.chapters = new ArrayList<Chapter>();
  }
 
  public String getIsbn() { return isbn; }
  public String getTitle() { return title; }
  public double getPrice() { return price; }
  public List<Author> getAuthors() { return authors; }
  public Publisher getPublisher() { return publisher; }
  public List<Chapter> getChapters() { return chapters; }
 
  public void setIsbn(String isbn) { this.isbn = isbn; }
  public void setTitle(String title) { this.title = title; }
  public void setPrice(double price) { this.price = price; }
  public void setAuthors(List<Author> authors) { this.authors = authors; }
  public void setPublisher(Publisher publisher) { this.publisher = publisher; }
  public void setChapters(List<Chapter> chapters) { this.chapters = chapters; }
 
  public void addAuthor(Author a) {
    for (Author author : authors) {
      if (author.getId() == a.getId()) {
        return;
      }
    }
    authors.add(a);
  }
 
  public void removeAuthor(Author a) { authors.remove(a); }
 
  public int getAuthorCount() { return authors.size(); }
 
  public void addChapter(Chapter c) { chapters.add(c); }
 
  public void removeChapter(Chapter c) { chapters.remove(c); }
 
  public int getPageCount() {
    int totalPages = 0;
    for (Chapter chapter : chapters) {
      totalPages += chapter.getPageCount();
    }
    return totalPages;
  }
 
  public int getChapterCount() { return chapters.size(); }
 
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
 
    sb.append(title);
    if (!authors.isEmpty()) {
      sb.append(" by ");
      for (int i = 0; i < authors.size(); i++) {
        sb.append(authors.get(i));
        if (i < authors.size() - 1) {
          sb.append(", ");
        }
      }
    }
    sb.append("\n");
 
    if (publisher != null) {
      sb.append("Publisher: ").append(publisher).append("\n");
    }
 
    sb.append(getChapterCount()).append(" chapters, ");
    sb.append(getPageCount()).append(" pages, $");
    sb.append(String.format("%.2f", price)).append(", [");
    sb.append(isbn).append("]");
 
    return sb.toString();
  }
}
BookTest.java
public class BookTest {
  public static void main(String[] args) {
    Address address =
        new Address("501 Boylston St.", "Boston", "Massachusetts", "02116");
    Publisher publisher =
        new Publisher(1, "Addison-Wesley Professional", "[email protected]");
    publisher.setAddress(address);
 
    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);
 
    book.setPublisher(publisher);
    book.addAuthor(author);
    book.addChapter(ch1);
    book.addChapter(ch2);
 
    System.out.println(book);
  }
}

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.

  1. Add the following Location class to your project:

    Location.java
    public 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;
      }
    }
    Location-city : String-country : String+Location(String, String)+getCity() : String+getCountry() : String+setCity(String) : void+seCountry(String) : void+toString() : String
  2. Add the following Room class to your project:

    Room.java
    public 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"));
      }
    }
    Room-number : int-floor : int-available : boolean+Room(int, int, boolean)+getNumber() : int+getFloor() : int+isAvailable() : boolean+setNumber(int) : void+setFloor(int) : void+setAvailable(boolean) : void+toString() : String
  3. Create a RoomType enumeration with three values: SINGLE, DOUBLE, SUITE.

  4. Make roomType: RoomType a field of the Room class. Add it to the fully parameterized constructor.

  5. Add a setter and getter for the roomType data member.

  6. Modify the toString() method of the Room 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.

  1. Provide two constructors: one takes the name, and the other takes the name and location.

  2. Provide setters and getters for all three fields.

  3. 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;
  4. 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 to false.
    • public void releaseRoom(int roomNumber): sets the room availability to true.
    • public boolean isRoomAvailable(int roomNumber): returns room availability.
    • public List<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 List<Room> roomsInFloor(int floorNumber): returns a list of the rooms in a specific floor number.
  5. 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

  1. 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

  1. Create a class named BookingApplication.
  2. The BookingApplication class has two fields: a name and a list of hotels.
  3. Discuss the usage of this application:
    1. What can you do with it?
    2. How can you benefit from the available code?
    3. What changes are needed to make it a fully-fledged application?
Solution
RoomType.java
public enum RoomType {
  SINGLE, DOUBLE, SUITE
}
Room.java
public class Room {
  private int number;
  private int floor;
  private boolean available;
  private RoomType roomType;
 
  public Room(int number, int floor, boolean available, RoomType roomType) {
    this.number = number;
    this.floor = floor;
    this.available = available;
    this.roomType = roomType;
  }
 
  public int getNumber() { return number; }
  public int getFloor() { return floor; }
  public boolean isAvailable() { return available; }
  public RoomType getRoomType() { return roomType; }
 
  public void setNumber(int number) { this.number = number; }
  public void setFloor(int floor) { this.floor = floor; }
  public void setAvailable(boolean available) { this.available = available; }
  public void setRoomType(RoomType roomType) { this.roomType = roomType; }
 
  @Override
  public String toString() {
    return String.format("[%-6s] Room number: %d\tFloor: %d\tAvailable: %s",
                         roomType, number, floor,
                         (this.isAvailable() ? "Yes" : "No"));
  }
}
Hotel.java
import java.util.ArrayList;
import java.util.List;
 
public class Hotel {
  private String name;
  private Location location;
  private List<Room> rooms;
 
  private final double SINGLE_ROOM_RATE = 355.5;
  private final double DOUBLE_ROOM_RATE = 515.5;
  private final double SUITE_RATE = 1079.5;
 
  public Hotel(String name) {
    this.name = name;
    this.rooms = new ArrayList<Room>();
  }
 
  public Hotel(String name, Location location) {
    this.name = name;
    this.location = location;
    this.rooms = new ArrayList<Room>();
  }
 
  public String getName() { return name; }
  public Location getLocation() { return location; }
  public List<Room> getRooms() { return rooms; }
 
  public void setName(String name) { this.name = name; }
  public void setLocation(Location location) { this.location = location; }
  public void setRooms(List<Room> rooms) { this.rooms = rooms; }
 
  public double getRoomRate(RoomType type) {
    switch (type) {
    case SINGLE:
      return SINGLE_ROOM_RATE;
    case DOUBLE:
      return DOUBLE_ROOM_RATE;
    case SUITE:
      return SUITE_RATE;
    default:
      return 0.0;
    }
  }
 
  public void addRoom(Room r) { rooms.add(r); }
 
  public void reserveRoom(int roomNumber) {
    for (Room room : rooms) {
      if (room.getNumber() == roomNumber) {
        room.setAvailable(false);
        return;
      }
    }
  }
 
  public void releaseRoom(int roomNumber) {
    for (Room room : rooms) {
      if (room.getNumber() == roomNumber) {
        room.setAvailable(true);
        return;
      }
    }
  }
 
  public boolean isRoomAvailable(int roomNumber) {
    for (Room room : rooms) {
      if (room.getNumber() == roomNumber) {
        return room.isAvailable();
      }
    }
    return false;
  }
 
  public List<Room> getAvailableRooms() {
    List<Room> availableRooms = new ArrayList<Room>();
    for (Room room : rooms) {
      if (room.isAvailable()) {
        availableRooms.add(room);
      }
    }
    return availableRooms;
  }
 
  public int getAvailableRoomsCount() { return getAvailableRooms().size(); }
 
  public int getRoomsCount() { return rooms.size(); }
 
  public List<Room> roomsInFloor(int floorNumber) {
    List<Room> floorRooms = new ArrayList<Room>();
    for (Room room : rooms) {
      if (room.getFloor() == floorNumber) {
        floorRooms.add(room);
      }
    }
    return floorRooms;
  }
 
  public double getTodaysIncome() {
    double income = 0.0;
    for (Room room : rooms) {
      if (!room.isAvailable()) {
        income += getRoomRate(room.getRoomType());
      }
    }
    return income;
  }
 
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("Hotel: ").append(name).append(". Address: ").append(location)
        .append("\n");
    sb.append("Room Count: ").append(getRoomsCount());
    sb.append(" (Available: ").append(getAvailableRoomsCount()).append(")\n");
    sb.append(String.format("Today's Income: $%.2f%n", getTodaysIncome()));
 
    for (Room room : rooms) {
      sb.append(room);
      sb.append(String.format(" @   $%,.2f%n", getRoomRate(room.getRoomType())));
    }
 
    return sb.toString();
  }
}
HotelTest.java
public class HotelTest {
  public static void main(String[] args) {
    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);
  }
}
BookingApplication.java
import java.util.ArrayList;
import java.util.List;
 
public class BookingApplication {
  private String name;
  private List<Hotel> hotels;
 
  public BookingApplication(String name) {
    this.name = name;
    this.hotels = new ArrayList<Hotel>();
  }
 
  public String getName() { return name; }
  public List<Hotel> getHotels() { return hotels; }
 
  public void setName(String name) { this.name = name; }
  public void setHotels(List<Hotel> hotels) { this.hotels = hotels; }
 
  public void addHotel(Hotel hotel) { hotels.add(hotel); }
 
  public void removeHotel(Hotel hotel) { hotels.remove(hotel); }
 
  public int getHotelCount() { return hotels.size(); }
 
  public List<Room> findAvailableRooms(RoomType type) {
    List<Room> availableRooms = new ArrayList<Room>();
    for (Hotel hotel : hotels) {
      for (Room room : hotel.getAvailableRooms()) {
        if (room.getRoomType() == type) {
          availableRooms.add(room);
        }
      }
    }
    return availableRooms;
  }
 
  public List<Hotel> findHotelsByCity(String city) {
    List<Hotel> cityHotels = new ArrayList<Hotel>();
    for (Hotel hotel : hotels) {
      if (hotel.getLocation() != null &&
          hotel.getLocation().getCity().equalsIgnoreCase(city)) {
        cityHotels.add(hotel);
      }
    }
    return cityHotels;
  }
 
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("Booking Application: ").append(name).append("\n");
    sb.append("Total Hotels: ").append(getHotelCount()).append("\n\n");
 
    for (Hotel hotel : hotels) {
      sb.append(hotel).append("\n");
    }
 
    return sb.toString();
  }
}
  1. What can you do with it?

    • Manage multiple hotels in different locations
    • Search for available rooms by type across all hotels
    • Find hotels in specific cities
    • Track room availability and reservations
    • Calculate daily income for hotels
  2. How can you benefit from the available code?

    • Provide a foundation for a hotel booking system
    • Demonstrate composition relationships between classes
    • Show how to manage collections of objects
    • Implement enumeration for room types
    • Provide methods for common booking operations
  3. What changes are needed to make it a fully-fledged application?

    • Add customer/guest management
    • Implement date-based reservations (check-in/check-out dates)
    • Add payment processing functionality
    • Create a user interface (GUI or web-based)
    • Add database persistence for data storage
    • Implement search and filtering capabilities
    • Add booking history and cancellation features
    • Include room amenities and descriptions
    • Add pricing variations (seasonal rates, discounts)
    • Implement authentication and authorization
    • Add email notifications for bookings
    • Include reviews and ratings system