Recently I had an interview and I was asked the following question. Given the following class/interface structure:
Question:
How can one implement interface EmployedStudent
to reuse code from StudentImpl
and EmployeeImpl
.
I suggested to compose Employee and Student into my implementation.
Based on the interviewer's reaction I don't think they found it to be the best solution. I spent a lot of time thinking about it but I cannot come up with another solution.
Create a class that implements both Employee
and Student
. In your class, create an instance of both EmployeeImpl
and StudentImpl
. Make your class delegate all method calls to either one of the objects then.
public class EmployedStudent implements Employee, Student {
private EmployeeImpl employee = new EmployeeImpl();
private StudentImpl student = new StudentImpl();
public int getSalary() {
return this.employee.getSalary();
}
public float getAverageGrade() {
return this.student.getAverageGrade();
}
}
So, you could have implements Employee, Student
internally delegating to both EmployeeImpl and StudentImpl, but also inherit from one implementation class.
Now the class name EmployedStudent (not StudyingEmployee or BothEmployeeAndStudent) suggests:
class EmployedStudent extends StudentImpl implements Employee {
Employee asEmployee = new EmployeeImpl();
Yeah, a tiny bit more efficient as only delegating to one other class.
The use-case is however far from realistic: all kind of combinations are thinkable of several classes. In that case your solution is more universal. Really universal, is a lookup-mechanism:
public class Person {
public <T> T as(Class<T> klazz) { ... }
}
Person person = ...;
Student asStudent = person.as(Student.class);
if (asStudent != null) {
...
}
Employee asEmployee = person.as(Employee.class);
if (asEmployee != null) {
asEmployee.quitJob();
asEmployee = person.as(Employee.class); // null
}
That is a lookup of capabilities. It typically can replace a cumbersome inheritance hierarchy, say of Vehicle, RoadVehicle, SwimmingVehicle (boat), FlyingVehicle (air plane), WaterAirplane (?), AmphibianTank (?) by using capabilities Swimming, Flying, Driving.
The difference is the entire decoupling.
As java doesn't support multiple inheritance, you could/should
The fields are then referred to by "our" implementation of the respective methods.
This is one of the design patterns from the GoF, I think it is the Proxy pattern.
With Java 8, you can move code into the interface itself. That solves the "multiple inheritance" problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With