我有一个People
类,以及继承自它的Student
和Employee
类。但是如果我有一个人Student
和Employee
......
......你将如何实现这一目标?
答案 0 :(得分:15)
这是一个不正确分析的问题域的典型例子。是的,在某些情况下,可能应该考虑"学生"作为一种" Person"和一个"员工"作为一种" Person",但是 - 根据您的问题域 - 它可能也不合适。
如果您的域名需要某个"学生"和#34;员工",您应该考虑"学生"之间的关系。和#34;人"您问题域中的 实际上是" is-a"关系。
在这种特殊情况下,作为学生可能只是特定人的属性。所以,John Doe是一个人,也可能有一个现在的职业" "学生"。在这种情况下,他可能会列出几个"当前职业"。在这样一个世界中,这种关系变得越来越紧密。而不是"是-a"。那么"学生"和"员工"成为"职业"。
的子类答案 1 :(得分:14)
根据评论:
这是一个面试问题,我想你可以在这里做出任何假设
如果是这种情况,唯一正确的答案是描述您的假设以及您如何解决这些假设。
如果您严格遵守要求,可以创建Student
和Employee
接口,并让不同的类实现它们:
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() {}
}
更进一步的是将work()
和learn()
的逻辑提取到辅助类,并StudentPerson
,EmployeePerson
和StudentEmployeePerson
调用他们分别。
但是,这个,恕我直言,错过了演习的重点。
同样有工作的学生仍然是学生。他不能与没有学生分开上课。
我创建了一个Role
界面,Student
和Employee
实现了该界面,并允许Person
拥有多个Role
s,所以他可以 一个学生和一个员工:
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();
}
}
}
编辑:
要回答评论中的问题,可以通过添加Role
来构建同时是学生和员工的人。为简单起见,下面的代码段假设这些类具有相关属性的构造函数,并且Person
具有向内部集添加和删除Role
的方法:
Person person = new Person("John Doe", 21, Sex.Male);
person.addRole(new Student("Stack Overflow University"));
person.addRole(new Employee("Secret Government Spy"));
答案 2 :(得分:4)
由于Java不允许多重继承,因此您应该为Student
和Employee
定义接口,而不是从它们继承为基类。
答案 3 :(得分:4)
您可以做的是,您可以将public class Employee
更改为public interface Employee
,然后您可以public class Student extends People implements Employee
你必须像这样工作,因为在java中,一个类最多只能从一个类继承。 欢呼声。
答案 4 :(得分:1)
在Java中,只能扩展一个超类。但是,Java提供了接口,一个类可以扩展多个接口。
您可以像这样组织您的类结构:
interface People
interface Student extends People
interface Employee extends People
那么你的就业学生可能是:
class EmployingStudent implements Student, Employee
如果People
是一个无法更改的类,您可以执行以下操作:
interface Student
interface Employee
class EmployingStudent implements Student, Employee
所以唯一的区别是学生和员工当时不会扩展人。