Polymorphism, Abstract Classes, and Interfaces
Objective
- Declare and implement abstract classes and interfaces.
- Apply composition, inheritance, and polymorphism.
Exercise 1*
-
Implement all four classes represented in the hierarchy of the following class diagram.
A Triangle’s area is 0.5f * height * width and a Rectangle’s area is height * width. Note: Symbols rendered using italics are abstract and # is used for protected field/methods.
-
Add an interface
Scalablewith ascale(double)method and realize it usingTriangleandSquare.
Solution
public abstract class Shape {
public Shape() {}
public abstract float area();
}public abstract class Shape2D extends Shape {
protected float width;
protected float height;
public Shape2D(float width, float height) {
this.width = width;
this.height = height;
}
}public interface Scalable {
void scale(float factor);
}public class Triangle extends Shape2D implements Scalable {
public Triangle(float width, float height) { super(width, height); }
@Override
public float area() {
return 0.5f * height * width;
}
@Override
public void scale(float factor) {
width *= factor;
height *= factor;
}
}public class Rectangle extends Shape2D implements Scalable {
public Rectangle(float width, float height) { super(width, height); }
@Override
public float area() {
return height * width;
}
@Override
public void scale(float factor) {
width *= factor;
height *= factor;
}
}Exercise 2*
Virtual Reserve
Create a virtual reserve with different types of animals, each with its unique behaviors.
- Use a base class
Animaland derived classes likeLion,Bear,Gull,Duck,Crow, andPenguin. Each animal has a name and an age. - Implement polymorphic methods such as
eat(),move(), andsound()for each animal. - Define interfaces for walking, flying, swimming, diving, and hibernating animals.
- Implement polymorphic methods such as
walk(),fly(),swim(),dive(), andhibernate()based on the abilities of each animal.
Solution
public abstract class Animal {
private String name;
private int age;
public Animal() {}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public abstract void eat();
public abstract void move();
public abstract void sound();
}public interface Diver {
void dive();
}public interface Flyer {
void fly();
}public interface Hibernator {
void hibernate();
}public interface Swimmer {
void swim();
}public interface Walker {
void walk();
}public class Bear extends Animal implements Walker, Swimmer, Hibernator {
public Bear(String name, int age) { super(name, age); }
@Override
public void eat() {
System.out.println(getName() + " the bear is eating fish and berries.");
}
@Override
public void move() {
walk();
}
@Override
public void sound() {
System.out.println(getName() + " the bear growls: GRRR!");
}
@Override
public void walk() {
System.out.println(getName() + " the bear is walking on four legs.");
}
@Override
public void swim() {
System.out.println(getName() + " the bear is swimming in the water.");
}
@Override
public void hibernate() {
System.out.println(getName() + " the bear is hibernating for winter.");
}
}public class Crow extends Animal implements Walker, Flyer {
public Crow(String name, int age) { super(name, age); }
@Override
public void eat() {
System.out.println(getName() + " the crow is eating seeds and insects.");
}
@Override
public void move() {
fly();
}
@Override
public void sound() {
System.out.println(getName() + " the crow caws: CAW CAW!");
}
@Override
public void walk() {
System.out.println(getName() + " the crow is hopping on two legs.");
}
@Override
public void fly() {
System.out.println(getName() + " the crow is flying in the sky.");
}
}public class Duck extends Animal implements Walker, Flyer, Swimmer, Diver {
public Duck(String name, int age) { super(name, age); }
@Override
public void eat() {
System.out.println(getName() + " the duck is eating seeds and insects.");
}
@Override
public void move() {
fly();
}
@Override
public void sound() {
System.out.println(getName() + " the duck quacks: QUACK!");
}
@Override
public void walk() {
System.out.println(getName() + " the duck is waddling on two legs.");
}
@Override
public void fly() {
System.out.println(getName() + " the duck is flying in the sky.");
}
@Override
public void swim() {
System.out.println(getName() + " the duck is swimming on the water.");
}
@Override
public void dive() {
System.out.println(getName() + " the duck is diving underwater for "
+ "food.");
}
}public class Gull extends Animal implements Walker, Flyer, Swimmer {
public Gull(String name, int age) { super(name, age); }
@Override
public void eat() {
System.out.println(getName() + " the gull is eating fish.");
}
@Override
public void move() {
fly();
}
@Override
public void sound() {
System.out.println(getName() + " the gull squawks: SQUAWK!");
}
@Override
public void walk() {
System.out.println(getName() + " the gull is walking on two legs.");
}
@Override
public void fly() {
System.out.println(getName() + " the gull is flying in the sky.");
}
@Override
public void swim() {
System.out.println(getName() +
" the gull is swimming on the water surface.");
}
}public class Lion extends Animal implements Walker {
public Lion(String name, int age) { super(name, age); }
@Override
public void eat() {
System.out.println(getName() + " the lion is eating meat.");
}
@Override
public void move() {
walk();
}
@Override
public void sound() {
System.out.println(getName() + " the lion roars: ROAR!");
}
@Override
public void walk() {
System.out.println(getName() + " the lion is walking on four legs.");
}
}public class Penguin extends Animal implements Walker, Swimmer, Diver {
public Penguin(String name, int age) { super(name, age); }
@Override
public void eat() {
System.out.println(getName() + " the penguin is eating fish.");
}
@Override
public void move() {
walk();
}
@Override
public void sound() {
System.out.println(getName() + " the penguin trumpets: HONK!");
}
@Override
public void walk() {
System.out.println(getName() + " the penguin is waddling on two legs.");
}
@Override
public void swim() {
System.out.println(getName() + " the penguin is swimming underwater.");
}
@Override
public void dive() {
System.out.println(getName() + " the penguin is diving deep for fish.");
}
}Exercise 3
Dates using LocalDate
-
Create a class
Personand an enumerationGenderusing the following code:Person.javaimport java.time.LocalDate; public class Person { private String name; private LocalDate birthDate; private Gender gender; public Person() {} public Person(String name, LocalDate birthDate, Gender gender) { this.name = name; this.birthDate = birthDate; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public LocalDate getBirthDate() { return birthDate; } public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; } public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; } }Gender.javapublic enum Gender { MALE, FEMALE; } -
Create a class
PersonTestusing the following code:PersonTest.javaimport java.time.LocalDate; public class PersonTest { public static void main(String[] args) { LocalDate date = LocalDate.of(1994, 9, 15); Person p1 = new Person("Jane", date, Gender.FEMALE); Person p2 = new Person("John", LocalDate.of(1995, 11, 20), Gender.MALE); if (p1.getBirthDate().isBefore(p2.getBirthDate())) System.out.println(p1.getName() + " is older than " + p2.getName()); else System.out.println(p2.getName() + " is older than " + p1.getName()); } }
Exercise 4
Create a project and implement the following class hierarchy:
Test your implementation using the following main() method:
import java.util.ArrayList;
import java.util.List;
public class PayableTest {
public static void main(String[] args) {
// create payable list
List<Payable> payables = new ArrayList<Payable>();
// populate list with objects that implement Payable
payables.add(new Invoice("01234", "Textbook", 2, 375.00));
payables.add(new Invoice("56789", "USB Disk", 3, 179.95));
payables.add(new SalariedEmployee("Ahmed", "Ali", "111-11-1111", 15000.00));
payables.add(
new HourlyEmployee("Fatima", "Saleh", "222-22-2222", 160.75, 40));
payables.add(
new CommissionedEmployee("Samir", "Sami", "333-33-3333", 100000, .06));
System.out.println("Invoices and Employees processed polymorphically:");
// generically process each element in array payables
for (Payable payable : payables) {
// output payable and its appropriate payment amount
System.out.printf("ObjectType: %s - PaymentAmount = QR %,.2f\n",
payable.getClass().getSimpleName(),
payable.getPaymentAmount());
// if SalariedEmployee then increase the salary by 10%
if (payable instanceof SalariedEmployee) {
// downcast Payable reference to
// SalariedEmployeeEmployee reference
SalariedEmployee salariedEmployee = (SalariedEmployee)payable;
double oldBaseSalary = salariedEmployee.getSalary();
salariedEmployee.setSalary(oldBaseSalary * 1.1);
System.out.printf("New salary with 10%% increase is: QR %,.2f\n",
salariedEmployee.getSalary());
}
}
}
}Solution
public interface Payable {
double getPaymentAmount();
}public class Invoice implements Payable {
private String partNumber;
private String partDescription;
private int quantity;
private double unitPrice;
public Invoice(String partNumber, String partDescription, int quantity,
double unitPrice) {
this.partNumber = partNumber;
this.partDescription = partDescription;
this.quantity = quantity;
this.unitPrice = unitPrice;
}
public String getPartNumber() { return partNumber; }
public void setPartNumber(String partNumber) { this.partNumber = partNumber; }
public String getPartDescription() { return partDescription; }
public void setPartDescription(String partDescription) {
this.partDescription = partDescription;
}
public int getQuantity() { return quantity; }
public void setQuantity(int quantity) { this.quantity = quantity; }
public double getUnitPrice() { return unitPrice; }
public void setUnitPrice(double unitPrice) { this.unitPrice = unitPrice; }
@Override
public double getPaymentAmount() {
return quantity * unitPrice;
}
@Override
public String toString() {
return String.format("Invoice [Part #: %s, Description: %s, Quantity: "
+ "%d, Unit Price: QR %.2f]",
partNumber, partDescription, quantity, unitPrice);
}
}public abstract class Employee implements Payable {
private String firstName;
private String lastName;
private String qid;
public Employee(String firstName, String lastName, String qid) {
this.firstName = firstName;
this.lastName = lastName;
this.qid = qid;
}
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public String getQid() { return qid; }
public void setQid(String qid) { this.qid = qid; }
@Override
public String toString() {
return String.format("%s %s (QID: %s)", firstName, lastName, qid);
}
}public class HourlyEmployee extends Employee {
private double wage;
private double hours;
public HourlyEmployee(String firstName, String lastName, String qid,
double wage, double hours) {
super(firstName, lastName, qid);
this.wage = wage;
this.hours = hours;
}
public double getWage() { return wage; }
public void setWage(double wage) { this.wage = wage; }
public double getHours() { return hours; }
public void setHours(double hours) { this.hours = hours; }
@Override
public double getPaymentAmount() {
return wage * hours;
}
@Override
public String toString() {
return String.format("Hourly Employee: %s, Wage: QR %.2f/hr, Hours: %.2f",
super.toString(), wage, hours);
}
}public class SalariedEmployee extends Employee {
private double salary;
public SalariedEmployee(String firstName, String lastName, String qid,
double salary) {
super(firstName, lastName, qid);
this.salary = salary;
}
public double getSalary() { return salary; }
public void setSalary(double salary) { this.salary = salary; }
@Override
public double getPaymentAmount() {
return salary;
}
@Override
public String toString() {
return String.format("Salaried Employee: %s, Salary: QR %.2f",
super.toString(), salary);
}
}public class CommissionedEmployee extends Employee {
private double grossSales;
private double commissionRate;
public CommissionedEmployee(String firstName, String lastName, String qid,
double grossSales, double commissionRate) {
super(firstName, lastName, qid);
this.grossSales = grossSales;
this.commissionRate = commissionRate;
}
public double getGrossSales() { return grossSales; }
public void setGrossSales(double grossSales) { this.grossSales = grossSales; }
public double getCommissionRate() { return commissionRate; }
public void setCommissionRate(double commissionRate) {
this.commissionRate = commissionRate;
}
@Override
public double getPaymentAmount() {
return grossSales * commissionRate;
}
@Override
public String toString() {
return String.format("Commissioned Employee: %s, Gross Sales: QR %.2f, "
+ "Commission Rate: %.2f%%",
super.toString(), grossSales, commissionRate * 100);
}
}Exercise 5
Default/Static Interface Methods/Fields
Expert Cleaning Co. provides cleaning services to the residents of The Pearl, Qatar. You are tasked with building an application to allow them to manage the cleaning services provided and the fees to be collected from the residents.
The class diagrams of the application are shown in the figures below:
You are required to modify the Vehicle, Car, Truck, and Resident classes to complete the implementation of the above inheritance hierarchy. Create the TransmissionType as an enumeration and import java.time.LocalDate. The methods’ descriptions are as follow:
-
Cleanableinterface:- Use the following
Mapvalues forfees:Map.of("Car", 10, "Truck", 15, "Unit", 25, "Villa", 50 );. ThegetFee(String)returns the fee from the map using the provided string. - Why is the method
getFee()static? - Implement
getCleaningFee()as a default method. It returns the product of the cleaning count with the cleaning fee of the class type. Hint: call thegetFee(String)method of the interface.
- Use the following
-
Vehicleclass:-
Implements the
Cleanableinterface. -
Modify the parameterized constructor so that it takes four arguments; add
plateNumberandregistrationDate. -
Add the setters and getters for the new fields, implementing the interface methods.
-
Modify the
toString()method so that it includesplateNumberandregistrationDatebut only if theplateNumbervalue is notnull, otherwise return"".
-
-
Carclass:- Modify the parameterized constructor to take six arguments; see the class diagram.
-
Truckclass:- Modify the parameterized constructor to take five arguments; see the class diagram.
-
Residenceclass:- Implement the class as shown in the class diagram. This class implements
Cleanable. - Implement the interface methods in a similar fashion to what you did in class
Vehicle. - Override the
toString()method to return a formatted string representation of theResidenceinstance.
- Implement the class as shown in the class diagram. This class implements
-
Unitclass:- Implement the class as shown in the class diagram. This class extends
Residence. - Override the
toString()method to return a formatted string representation of aUnitinstance.
- Implement the class as shown in the class diagram. This class extends
-
Villaclass:- Implement the class as shown in the class diagram. This class extends
Residence. - Override the
toString()method to return a formatted string representation of aVillainstance.
- Implement the class as shown in the class diagram. This class extends
-
Residentclass:-
Copy the
Personclass from Exercise 8.1 toResident. -
Add a
residencefield and generate its setter and getter. -
Add a list of
vehiclesas a private field and create its getter method; a setter is not required. -
Add the
addVehicle()method which adds aVehicleparameter to the list of vehicles. It should check that the parameter value is notnulland that it does not already exist in the list of vehicles. -
Add the following methods:
public Vehicle getVehicle(String plateNumber) { // searches for a vehicle with plateNumber and returns it or returns null if // not found. } public void deleteVehicle(String plateNumber) { // searches for a vehicle with plateNumber and deletes it if found. }
-
Create a CleaningCoApp class with a main() method to test the application:
-
Create a list of residents to store all the residents using the services of Expert Cleaning Co.
-
Based on the example data provided below, create instances of
Resident, and add them to the list of residents. Each resident lives in aUnitor aVillaand has a couple ofVehicles.John Doe lives in a Villa @ 55 La Plage Villas, The Pearl, Doha. The villa has 6 rooms and 2 floors. He requests cleaning his villa 4 times a month. He has the following cars:
Plate Number Wheels Weight Passengers Transmission Registration Date Cleaning Count 1201 4 1,950 5 Automatic 2022-03-22 5 He owns the following trucks:
Plate Number Wheels Weight Load Registration Date Cleaning Count 4211 12 4,000 12,000 2023-07-01 5 8003 10 3,000 8,000 2015-08-24 1 8025 12 4,500 15,000 2019-02-21 2 Jane Doe lives in a Unit @ 508 West Porto Drive, The Pearl, Doha. The Unit number is 16 at Porto Arabia building. The unit has 2 rooms. She requests cleaning her unit 3 times a month. She has the following cars:
Plate Number Wheels Weight Passengers Transmission Registration Date Cleaning Count 4907 4 1,950 5 Automatic 2022-03-18 5 9093 4 3,000 8 Manual 2018-12-01 1 -
Loop through the list of residents and display for each resident:
- Resident name and address,
- residence type,
- the number of vehicles, and
- the cleaning fees to be paid.
Solution
import java.util.Map;
public interface Cleanable {
static Map<String, Integer> fees =
Map.of("Car", 10, "Truck", 15, "Unit", 25, "Villa", 50);
static int getFee(String type) { return fees.getOrDefault(type, 0); }
int getCleaningCount();
void setCleaningCount(int count);
default double getCleaningAmount() {
return getCleaningCount() * getFee(getClass().getSimpleName());
}
}import java.time.LocalDate;
public abstract class Vehicle implements Cleanable {
private String plateNumber;
private int wheels;
private double weight;
private LocalDate registrationDate;
private int cleaningCount;
public Vehicle() {}
public Vehicle(String plateNumber, int wheels, double weight,
LocalDate registrationDate) {
this.plateNumber = plateNumber;
this.wheels = wheels;
this.weight = weight;
this.registrationDate = registrationDate;
}
public String getPlateNumber() { return plateNumber; }
public void setPlateNumber(String plateNumber) {
this.plateNumber = plateNumber;
}
public int getWheels() { return wheels; }
public void setWheels(int wheels) { this.wheels = wheels; }
public double getWeight() { return weight; }
public void setWeight(double weight) { this.weight = weight; }
public LocalDate getRegistrationDate() { return registrationDate; }
public void setRegistrationDate(LocalDate registrationDate) {
this.registrationDate = registrationDate;
}
@Override
public int getCleaningCount() {
return cleaningCount;
}
@Override
public void setCleaningCount(int cleaningCount) {
this.cleaningCount = cleaningCount;
}
@Override
public String toString() {
if (plateNumber != null) {
return String.format("Plate #: %s, Registration Date: %s", plateNumber,
registrationDate);
}
return "";
}
}public enum TransmissionType {
AUTOMATIC,
MANUAL;
}import java.time.LocalDate;
public class Car extends Vehicle {
private int passengers;
private TransmissionType transmission;
public Car() {}
public Car(String plateNumber, int wheels, double weight,
LocalDate registrationDate, int passengers,
TransmissionType transmission) {
super(plateNumber, wheels, weight, registrationDate);
this.passengers = passengers;
this.transmission = transmission;
}
public int getPassengers() { return passengers; }
public void setPassengers(int passengers) { this.passengers = passengers; }
public TransmissionType getTransmission() { return transmission; }
public void setTransmission(TransmissionType transmission) {
this.transmission = transmission;
}
@Override
public String toString() {
return String.format("Car [%s, Wheels: %d, Weight: %.0f kg, Passengers: "
+ "%d, Transmission: %s, Cleaning Count: %d]",
super.toString(), getWheels(), getWeight(), passengers,
transmission, getCleaningCount());
}
}import java.time.LocalDate;
public class Truck extends Vehicle {
private double load;
public Truck() {}
public Truck(String plateNumber, int wheels, double weight,
LocalDate registrationDate, double load) {
super(plateNumber, wheels, weight, registrationDate);
this.load = load;
}
public double getLoad() { return load; }
public void setLoad(double load) { this.load = load; }
public double getWheelLoad() { return (getWeight() + load) / getWheels(); }
@Override
public String toString() {
return String.format("Truck [%s, Wheels: %d, Weight: %.0f kg, Load: %.0f "
+ "kg, Wheel Load: %.2f kg, Cleaning Count: %d]",
super.toString(), getWheels(), getWeight(), load,
getWheelLoad(), getCleaningCount());
}
}public abstract class Residence implements Cleanable {
private String street;
private int roomCount;
private int cleaningCount;
public Residence() {}
public Residence(String street, int roomCount) {
this.street = street;
this.roomCount = roomCount;
}
public String getStreet() { return street; }
public void setStreet(String street) { this.street = street; }
public int getRoomCount() { return roomCount; }
public void setRoomCount(int roomCount) { this.roomCount = roomCount; }
@Override
public int getCleaningCount() {
return cleaningCount;
}
@Override
public void setCleaningCount(int cleaningCount) {
this.cleaningCount = cleaningCount;
}
@Override
public String toString() {
return String.format("Street: %s, Rooms: %d, Cleaning Count: %d", street,
roomCount, cleaningCount);
}
}public class Unit extends Residence {
private String buildingName;
private int unitNumber;
public Unit() {}
public Unit(String street, int roomCount, String buildingName,
int unitNumber) {
super(street, roomCount);
this.buildingName = buildingName;
this.unitNumber = unitNumber;
}
public String getBuildingName() { return buildingName; }
public void setBuildingName(String buildingName) {
this.buildingName = buildingName;
}
public int getUnitNumber() { return unitNumber; }
public void setUnitNumber(int unitNumber) { this.unitNumber = unitNumber; }
@Override
public String toString() {
return String.format("Unit [Building: %s, Unit #: %d, %s]", buildingName,
unitNumber, super.toString());
}
}public class Villa extends Residence {
private int floorsCount;
public Villa() {}
public Villa(String street, int roomCount, int floorsCount) {
super(street, roomCount);
this.floorsCount = floorsCount;
}
public int getFloorsCount() { return floorsCount; }
public void setFloorsCount(int floorsCount) {
this.floorsCount = floorsCount;
}
@Override
public String toString() {
return String.format("Villa [Floors: %d, %s]", floorsCount,
super.toString());
}
}import java.util.ArrayList;
import java.util.List;
public class Resident {
private int id;
private String name;
private List<Vehicle> vehicles;
private Residence residence;
public Resident() { this.vehicles = new ArrayList<>(); }
public Resident(int id, String name) {
this.id = id;
this.name = name;
this.vehicles = new ArrayList<>();
}
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Residence getResidence() { return residence; }
public void setResidence(Residence residence) { this.residence = residence; }
public List<Vehicle> getVehicles() { return vehicles; }
public void addVehicle(Vehicle vehicle) {
if (vehicle != null && !vehicles.contains(vehicle)) {
vehicles.add(vehicle);
}
}
public Vehicle getVehicle(String plateNumber) {
for (Vehicle vehicle : vehicles) {
if (vehicle.getPlateNumber().equals(plateNumber)) {
return vehicle;
}
}
return null;
}
public void deleteVehicle(String plateNumber) {
Vehicle vehicle = getVehicle(plateNumber);
if (vehicle != null) {
vehicles.remove(vehicle);
}
}
@Override
public String toString() {
return String.format("Resident [ID: %d, Name: %s]", id, name);
}
}import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class CleaningCoApp {
public static void main(String[] args) {
List<Resident> residents = new ArrayList<>();
Resident johnDoe = new Resident(1, "John Doe");
Villa johnVilla = new Villa("55 La Plage Villas, The Pearl, Doha", 6, 2);
johnVilla.setCleaningCount(4);
johnDoe.setResidence(johnVilla);
Car johnCar = new Car("1201", 4, 1950, LocalDate.of(2022, 3, 22), 5,
TransmissionType.AUTOMATIC);
johnCar.setCleaningCount(5);
johnDoe.addVehicle(johnCar);
Truck truck1 = new Truck("4211", 12, 4000, LocalDate.of(2023, 7, 1), 12000);
truck1.setCleaningCount(5);
johnDoe.addVehicle(truck1);
Truck truck2 = new Truck("8003", 10, 3000, LocalDate.of(2015, 8, 24), 8000);
truck2.setCleaningCount(1);
johnDoe.addVehicle(truck2);
Truck truck3 =
new Truck("8025", 12, 4500, LocalDate.of(2019, 2, 21), 15000);
truck3.setCleaningCount(2);
johnDoe.addVehicle(truck3);
residents.add(johnDoe);
Resident janeDoe = new Resident(2, "Jane Doe");
Unit janeUnit = new Unit("508 West Porto Drive, The Pearl, Doha", 2,
"Porto Arabia", 16);
janeUnit.setCleaningCount(3);
janeDoe.setResidence(janeUnit);
Car janeCar1 = new Car("4907", 4, 1950, LocalDate.of(2022, 3, 18), 5,
TransmissionType.AUTOMATIC);
janeCar1.setCleaningCount(5);
janeDoe.addVehicle(janeCar1);
Car janeCar2 = new Car("9093", 4, 3000, LocalDate.of(2018, 12, 1), 8,
TransmissionType.MANUAL);
janeCar2.setCleaningCount(1);
janeDoe.addVehicle(janeCar2);
residents.add(janeDoe);
System.out.println("Expert Cleaning Co. - Resident Summary");
System.out.println("=".repeat(80));
System.out.println();
for (Resident resident : residents) {
System.out.println("Resident: " + resident.getName());
System.out.println("Address: " + resident.getResidence().getStreet());
System.out.println("Residence Type: " +
resident.getResidence().getClass().getSimpleName());
System.out.println("Number of Vehicles: " +
resident.getVehicles().size());
double totalFees = 0;
if (resident.getResidence() != null) {
double residenceFee = resident.getResidence().getCleaningAmount();
totalFees += residenceFee;
System.out.printf(" - Residence Cleaning Fee: QR %.2f\n",
residenceFee);
}
for (Vehicle vehicle : resident.getVehicles()) {
double vehicleFee = vehicle.getCleaningAmount();
totalFees += vehicleFee;
System.out.printf(" - %s (Plate: %s) Cleaning Fee: QR %.2f\n",
vehicle.getClass().getSimpleName(),
vehicle.getPlateNumber(), vehicleFee);
}
System.out.printf("Total Cleaning Fees: QR %.2f\n", totalFees);
System.out.println("-".repeat(80));
System.out.println();
}
}
}Exercise 6+
Vehicle Hierarchy
Consider a hierarchy of vehicles with a base class Vehicle and derived classes like Car, Bicycle, and Boat. Each vehicle can have a move() method, and each derived class can implement it differently, simulating how different types of vehicles move.
Game Characters
Design a simple video game with characters like warriors, mages, and archers. Create a base class Character and subclasses for each character type. Implement polymorphic methods like attack(), defend(), and specialAbility() for each character.
Library System
Design a library management system with a base class LibraryItem and derived classes like Book, DVD, and Magazine. Each item type can have its own implementation of methods like checkOut() and returnItem(). Use polymorphism to handle different library items within the same system.
Vehicle Fleet
Create a program to manage a fleet of vehicles, including cars, trucks, and motorcycles. Define a base class Vehicle and subclasses for each vehicle type. Use polymorphism to handle common operations like start(), stop(), and fuelUp(). How would update your class hierarchy to account for electric vehicles?
Banking Transactions
Create a banking system with a base class Account and derived classes like SavingsAccount, CheckingAccount, and LoanAccount. Each account type can implement methods for depositing, withdrawing, and checking balances.
Payment Methods
Create a payment processing system with a base class PaymentMethod and derived classes like CreditCard, PayPal, and BankTransfer. Each payment method can have its own implementation for processing payments.
Online Shopping Cart
Develop an online shopping cart system with a base class Product and derived classes for product categories like Electronics, Clothing, and Books. Each product type can have its own pricing and shipping logic, making use of polymorphism to manage the cart.