I have a People
class, and Student
and Employee
classes which inherit from it. But if I have a person who is both a Student
and an Employee
...
... How would you go about implementing this?
That's a classic example of an improperly analyzed problem domain. Yes, in some situations, it may be proper to think of "Student" as a type of "Person" and an "Employee" as a type of "Person", but - depending on your problem domain - it may also not be appropriate.
If your domain requires that something be both a "Student" and an "Employee", you should consider if the relation between "Student" and "Person" in your problem domain is really an "is-a" relationship.
It could be that in this particular case, being a student is merely an attribute of a particular person. So, John Doe is a person, who may also have a "current occupation" of "Student". In this case, he may have a list of several "current occupations". And the relationship in such a world becomes "has-a" rather than "is-a". So "Student" and "Employee" become subclasses of "Occupation".
As per the comment:
it is a interview question, i think you can make any assumption here
If this is the case, the only correct answer is to describe your assumptions, and how you address them.
If you strictly adhere to the requirements, you could make Student
and Employee
interfaces and have different classes implement them:
public interface Student {
void learn();
}
public interface Employee {
void work();
}
public class Person {
// properties, getters and setters for name, age, sex, etc.
}
public class StudentPerson extends Person implements Student {
@Override
public void learn() {}
}
public class EmployeePerson extends Person implements Employee {
@Override
public void work() {}
}
public class StudentEmployeePerson extends Person implements Student, Employee {
@Override
public void work();
@Override
public void learn() {}
}
Taking this an extra mile would be to extract the logic of work()
and learn()
to helper classes, and have StudentPerson
, EmployeePerson
and StudentEmployeePerson
call them respectively.
But this, IMHO, missed the point of the exercise.
A student who also has a job is still a student. He cannot be a separate class from a student who doesn't.
I'd create a Role
interface, have Student
and Employee
implement it, and allow a Person
to have multiple Role
s, so he can be both a student and an employee:
public interface Role {
void perform();
}
public class Student implements Role {
@Override
void perform() { /* go study */ }
}
public class Employee implements Role {
@Override
void perform() { /* go work */ }
}
public class Person {
// properties, getters and setters for name, age, sex, etc.
private Set<Role> roles = /* initialized somehow */
public void doStuff() {
for (Role role : roles) {
role.perform();
}
}
}
EDIT:
To answer the question in the comment, a person who is both a student and an employee would be constructed by adding Role
s. For simplicity's sake the snippet below assumes that these classes have constructors from the relevant properties, and that Person
has methods to add and remove the Role
s to the internal set:
Person person = new Person("John Doe", 21, Sex.Male);
person.addRole(new Student("Stack Overflow University"));
person.addRole(new Employee("Secret Government Spy"));
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