如果我有以下对象:
Teacher extends Person
Student extends Person
然后,我在服务中有一个函数,它返回人员列表/数组等,但列表中的某些项目可能是教师,有些可能是学生。
在返回端,我希望用户能够检查每个元素的实例以确定它是学生还是教师。
构建此代码的最佳方法是什么。
所以,在服务中,我想要这样的东西:
public LinkedList<Person> getPersonByID(List<String id>);
如果我有以下对象:
Teacher extends Person
Student extends Person
然后,我在服务中有一个函数,它返回人员列表/数组等,但列表中的某些项目可能是教师,有些可能是学生。
在返回端,我希望用户能够检查每个元素的实例以确定它是学生还是教师。
构建此代码的最佳方法是什么。
所以,在服务中,我想要这样的东西:
public LinkedList<Person> getPersonByID(List<String id>);
最好的方法是使用多态性来消除显式检查 Person 类型的需要。你如何做到这一点,取决于你的任务,也许你可以提供更多的代码。
这可以在不instanceof
使用访问者模式的情况下解决。(如果使用普通的多态性技术无法解决问题,则可能首选这种方法,因为应该避免使用 instanceof。)
这是对我的回答的改编,在ideone.com上有一个演示:
import java.util.*;
public class Test {
public static void main(String[] args) {
List<Person> somePersons = new LinkedList<Person>();
somePersons.add(new Teacher());
somePersons.add(new Student());
somePersons.add(new Teacher());
for (Person p : somePersons)
p.visit(new Visitor() {
@Override
public void accept(Student student) {
student.learn("stuff");
}
@Override
public void accept(Teacher teacher) {
teacher.teach("some other stuff");
}
});
}
}
interface Visitor {
public void accept(Teacher a);
public void accept(Student b);
}
abstract class Person {
String name;
abstract void visit(Visitor v);
}
class Teacher extends Person {
public void teach(String toTeach) {
System.out.println("I'm teaching " + toTeach);
}
public void visit(Visitor sv) {
sv.accept(this);
}
}
class Student extends Person {
public void learn(String toLearn) {
System.out.println("I'm learning " + toLearn);
}
public void visit(Visitor sv) {
sv.accept(this);
}
}
Java中有一个instanceof
关键字可以在运行时用来检查对象的类型。所以,读起来像这样的代码:
LinkedList<Person> foo = getPersonByID(some_id_list);
for (Person p: foo)
if (p instanceof Teacher)
// do stuff
else if (p instanceof Student)
// again
else
// ...
如果您知道以后需要更大的灵活性,您可以考虑从is-a 转变为has-a关系。
has-a是 Person 可以拥有的一组角色,例如教师角色或学生角色。或者两者兼而有之,就像一个学生在讲课一样。
一个简单的例子来展示这种方法:
public enum Role {TEACHER, STUDENT}
public class Person {
Set<Role> roles = new HashSet<Role>();
public Person() {
// a person does not have roles initially
}
public boolean addRole(Role aRole) {
return roles.add(aRole);
}
public boolean hasRole(Role aRole) {
return roles.contains(aRole);
}
// ...
}
public void someMethod(Person person) {
if (Person.hasRole(Role.TEACHER)) {
// do teacher stuff
}
if (Person.hasRole(Role.STUDENT)) {
// do student stuff
// Note: persons may be Teacher AND Student at the same time
}
}
您始终可以使用以下代码检查给定实例是否是给定类型的类型
if( selectedPerson instanceof Student)
...