Inheritance, Specialization, and Generalization
Objective
- Apply inheritance in application development.
- Write classes with overridden methods.
Exercise 1*
-
Create a new project, a package named
model, and a package namedtest. -
In the
modelpackage, create a class calledPersonthat has two data members:id:intandname:String. Add corresponding setter/getter methods. -
Create a new class named
Employeethat inherits (specializes) classPersonand has one additional data member:noOfChildren. -
Add setter/getter method for this new field.
According to this, the superclass (parent) is
_______and the subclass (child) is_______. -
In the
modelpackage, create a new classEmployeeTestwith amain()method. In themain()method, create an object of typeEmployee. -
Using setter methods, set the object’s data as follows:
idto123,nameto"Khaled", andnoOfChildrento2.Note that the methods
setId()andsetName()are not defined in theEmployeeclass but inherited fromPerson. -
Output the name, ID, and number of children for the above employee.
-
In class
Employee, add a constructor that receives one parameter (int) to initialize the fieldnoOfChildren. This results in an error. Why?To solve this, add a default constructor in the
Employeeclass. -
Add a constructor to
Personthat receives two parameters to initializeidandname. Add an output statement in this constructor to print"Person constructor called". This results in an error. Why?To solve this, add a default constructor in the
Personclass. -
Add a constructor in class
Employeethat receives three parameters:int,String, andintto initialize all data members.-
Can you access the
idandnamefields directly in this constructor? -
If not, then how to solve this issue?
One solution is to use the setters of these fields. An alternative way is to explicitly call the constructor of the superclass. How to do that?
-
Use the keyword
superto call the superclass’s constructor to initialize the data, in a similar fashion to the use ofthis()to call an overloaded constructor. Also add output statements in this constructor to print"Employee constructor called". -
Can you make the superclass constructor call as the last statement?
-
-
In the
main()method, create a new object as follows:Employee emp = new Employee(124, "Ameen", 1);Run the program. What is the output? What do you conclude regarding the order of constructor calls?
-
Change the access modifiers of
idandnamein classPersontoprotectedinstead ofprivate. Now try to access them directly in theEmployeeclass. Are they accessible?In the
main()method, try to access theidandnameof objectemp. Are they accessible?Notice that
EmployeeTestis not a member of the inheritance hierarchy, but it has access to the protected members. Explain and elaborate.Refer to Controlling Access to Members of a Class (opens in a new tab) to learn more about access modifiers:
Modifier Class Package Subclass World publicprotectedprivate -
Move the
EmployeeTestclass to thetestpackage that you created earlier. Explain the errors you get when you try to run your application and propose ways to fix them. -
Create the
publicmethodtoString()in classPersonthat returns the person’s id and name as comma-separated values (CSV). Output the details ofempusingtoString(). -
In class
Employee, create a public methodtoString()to return all the employee’s data: ID, name, and number of children as comma-separated values.- Having two methods with the same name and signature, one in the superclass and one in the subclass is called
_______. - How to call the superclass method
toString()from the subclass?
- Having two methods with the same name and signature, one in the superclass and one in the subclass is called
-
Modify the access modifier of
toString()in classEmployeetoprotectedinstead ofpublic. What do you conclude? -
Now restore
toString()’s access modifier topublic. Also make theidandnamefields private and fix all references made to them. Also remove the output statements from the constructors of thePersonandEmployeeclasses, as they are no longer needed.
Solution
package model;
public class Person {
private int id;
private String name;
public Person() {}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
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; }
@Override
public String toString() {
return id + "," + name;
}
}
package model;
public class Employee extends Person {
private int noOfChildren;
public Employee() {}
public Employee(int noOfChildren) { this.noOfChildren = noOfChildren; }
public Employee(int id, String name, int noOfChildren) {
super(id, name);
this.noOfChildren = noOfChildren;
}
public int getNoOfChildren() { return noOfChildren; }
public void setNoOfChildren(int noOfChildren) {
this.noOfChildren = noOfChildren;
}
@Override
public String toString() {
return super.toString() + "," + noOfChildren;
}
}package test;
import model.Employee;
public class EmployeeTest {
public static void main(String[] args) {
Employee emp1 = new Employee();
emp1.setId(123);
emp1.setName("Khaled");
emp1.setNoOfChildren(2);
System.out.println("Employee 1 Details:");
System.out.println("ID: " + emp1.getId());
System.out.println("Name: " + emp1.getName());
System.out.println("Number of Children: " + emp1.getNoOfChildren());
System.out.println();
Employee emp2 = new Employee(124, "Ameen", 1);
System.out.println("Employee 2 Details:");
System.out.println(emp2);
System.out.println();
}
}Exercise 2
-
Add the following three classes to your project:
Vehicle.javapackage model; public class Vehicle { private int wheels; private double weight; public Vehicle() {} public Vehicle(int wheels, double weight) { this.wheels = wheels; this.weight = weight; } 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; } @Override public String toString() { String dashes = ""; String className = getClass().getSimpleName(); for (int i = 0; i < className.length(); i++) { dashes += "-"; } return className + "\n" + dashes + "\n" + "Wheels: " + wheels + "\n" + "Weight: " + weight + "\n"; } }Car.javapackage model; public class Car extends Vehicle { private int passengers; public Car() {} public Car(int wheels, double weight, int passengers) { super(wheels, weight); this.passengers = passengers; } public int getPassengers() { return passengers; } public void setPassengers(int passengers) { this.passengers = passengers; } @Override public String toString() { return super.toString() + "Passengers: " + passengers + "\n"; } }VehicleTest.javapackage test; import model.*; public class VehicleTest { public static void main(String[] args) { Vehicle bicycle = new Vehicle(2, 20.0); Car sedan = new Car(); Car toyota = new Car(4, 2000.0, 5); sedan.setWheels(4); sedan.setPassengers(4); sedan.setWeight(1500.0); System.out.println(bicycle); System.out.println(sedan); System.out.println(toyota); } } -
Run the
VehicleTestclass’smain()method. -
Add to the
Vehicleclass the public methodgetAsCSV()that returns the field values as comma-separated values. Let the last value in the comma-separated string be the name of the class preceded with a comma.Hint: Use the
getClass().getSimpleName()from theObjectclass. Override this method in theCarclass. Display thebicycle,sedan, andtoyotaobjects as comma-separated values. -
Add a class called
Truckto themodelpackage that inherits from theVehicleclass.Truckobjects have the fields:- number of wheels (
wheels) - truck weight (
weight) - load capacity (
capacity)
and the methods:
- getters and setters
- no-argument constructor
- parametrized constructor
getWheelLoad(): returns the wheel load which is equal to(weight + capacity) / wheels.toString(): overrides the superclass method by adding the truck details and the wheel load to the string generated by the superclass. Let the returned string be properly formatted.getAsCSV(): overrides the superclass method by returning all the values of a truck object as comma-separated values without including the wheel load.
- number of wheels (
-
Update the
main()method in theVehicleTestto perform the following:- Create a
Truckobject named"volvo"with the data:- Number of wheels: 12
- Truck weight: 4,000 kg
- Load capacity: 12,000 kg
- Display the
"volvo"data using bothtoString()andgetAsCSV()methods.
- Create a
Solution
package model;
public class Vehicle {
private int wheels;
private double weight;
public Vehicle() {}
public Vehicle(int wheels, double weight) {
this.wheels = wheels;
this.weight = weight;
}
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 String getAsCSV() {
return wheels + "," + weight + "," + getClass().getSimpleName();
}
@Override
public String toString() {
String dashes = "";
String className = getClass().getSimpleName();
for (int i = 0; i < className.length(); i++) {
dashes += "-";
}
return className + "\n" + dashes + "\n"
+ "Wheels: " + wheels + "\n"
+ "Weight: " + weight + "\n";
}
}package model;
public class Car extends Vehicle {
private int passengers;
public Car() {}
public Car(int wheels, double weight, int passengers) {
super(wheels, weight);
this.passengers = passengers;
}
public int getPassengers() { return passengers; }
public void setPassengers(int passengers) { this.passengers = passengers; }
@Override
public String getAsCSV() {
return getWheels() + "," + getWeight() + "," + passengers + "," +
getClass().getSimpleName();
}
@Override
public String toString() {
return super.toString() + "Passengers: " + passengers + "\n";
}
}package model;
public class Truck extends Vehicle {
private double capacity;
public Truck() {}
public Truck(int wheels, double weight, double capacity) {
super(wheels, weight);
this.capacity = capacity;
}
public double getCapacity() { return capacity; }
public void setCapacity(double capacity) { this.capacity = capacity; }
public double getWheelLoad() {
return (getWeight() + capacity) / getWheels();
}
@Override
public String getAsCSV() {
return getWheels() + "," + getWeight() + "," + capacity + "," +
getClass().getSimpleName();
}
@Override
public String toString() {
return super.toString() + "Capacity: " + capacity + "\n"
+ "Wheel Load: " + getWheelLoad() + "\n";
}
}package test;
import model.Car;
import model.Truck;
import model.Vehicle;
public class VehicleTest {
public static void main(String[] args) {
Vehicle bicycle = new Vehicle(2, 20.0);
Car sedan = new Car();
Car toyota = new Car(4, 2000.0, 5);
sedan.setWheels(4);
sedan.setPassengers(4);
sedan.setWeight(1500.0);
System.out.println(bicycle);
System.out.println(sedan);
System.out.println(toyota);
System.out.println("CSV Output:");
System.out.println(bicycle.getAsCSV());
System.out.println(sedan.getAsCSV());
System.out.println(toyota.getAsCSV());
System.out.println();
Truck volvo = new Truck(12, 4000.0, 12000.0);
System.out.println("Truck Details:");
System.out.println(volvo);
System.out.println("Truck CSV:");
System.out.println(volvo.getAsCSV());
}
}Exercise 3
-
In the
testpackage, create a new class calledPersonTestwhich contains amain()method that tests thePersonclass by creating aListofPersoninstances, where the elements are initialized using the following data:ID Name 1318 Jane Doe 2571 John Doe 5376 Sara Smith -
Write statements to output the contents of the 3 instances then save your file and run it.
Solution
package test;
import java.util.ArrayList;
import java.util.List;
import model.Person;
public class PersonTest {
public static void main(String[] args) {
List<Person> persons = new ArrayList<>();
persons.add(new Person(1318, "Jane Doe"));
persons.add(new Person(2571, "John Doe"));
persons.add(new Person(5376, "Sara Smith"));
System.out.println("Person List:");
for (Person person : persons) {
System.out.println(person);
}
System.out.println(persons);
}
}Exercise 4+
- In the
modelpackage, create a class calledStudentthat inherits from thePersonclass. A student has three data members:id:int,name:String, andmajor:String. - Add setter/getter methods for the additional field. Also add a
toString()method that returns all the student details as a string. - In the
StudentTestclass, create twoStudentinstances. - Display the details of the two students you have just created.
Solution
package model;
public class Student extends Person {
private String major;
public Student() {}
public Student(int id, String name, String major) {
super(id, name);
this.major = major;
}
public String getMajor() { return major; }
public void setMajor(String major) { this.major = major; }
@Override
public String toString() {
return super.toString() + "," + major;
}
}package test;
import model.Student;
public class StudentTest {
public static void main(String[] args) {
Student student1 = new Student(201817, "John Doe", "Computer Science");
Student student2 = new Student(201922, "Jane Doe", "Computer Engineering");
System.out.println("Student Details:");
System.out.println(student1);
System.out.println(student2);
}
}