我有两个类Student和Tutor。导师基本上是一名学生(导师延伸学生)谁拥有facultyID。一旦他的合同完成,他就回到只是一名学生。那么我能否以某种方式将他转回他以前的学生卷?Java,是否有可能将对象从子类转换为超类对象
回答
你真正想要做的是使用composition and not inheritance。将所有对象保留为类型Student
,然后按需要临时将TutorRole
的行为分配给每个实例Student
。
使用此设计,您的Student
类将包含类型为TutorRole
的属性(成员变量),您可以在运行时添加或删除该属性。添加一个isTutor()
方法将允许您以清晰简洁的方式确定学生是否在运行时是导师。
TutorRole
类将封装作为Tutor的行为(即方法)。
/*
* The TutorRole can be set at runtime
*/
public class Student {
private String facultyId;
private TutorRole tutorRole = null;
public boolean isTutor() {
return !(tutorRole == null);
}
public void doTutorStuff() {
if(isTutor()) {
tutorRole.doTutorStuff();
}
else {
throw new NotTutorException();
}
}
public void setTutorRole(TutorRole tutorRole) {
this.tutorRole = tutorRole;
}
}
/*
* Ideally this class should implement a generic interface, but I'll keep this simple
*/
public class TutorRole {
public void doTutorStuff() {
// implementation here
}
}
/*
* Now let's use our classes...
*/
Student st = new Student(); // not a tutor
st.setTutorRole(new TutorRole()); // now a tutor
if(st.isTutor()) {
st.doTutorStuff();
}
st.setTutorRole(null); // not a tutor anymore
的另一种方法是有一个Tutor
类包含对Student
对象的引用,但是这取决于你将如何与学生进行互动,各地要编码这个导师在哪条路对象。
你可以转换作为学生的导师,所以你的代码在编译时对待他,但对象将保持一个导师,所以调用任何重写的方法将导致调用Tutor类的版本。
要做的那种“转换”,你正在寻找的唯一方法是创建一个新的学生对象,并给它所有的导师的属性。
由于您发现需要进行此转换,因此您可能需要重新考虑类结构。例如,也许学生和导师都应该只是人,而每个人都可以有学生或教师的角色。
请您详细说明一下吗?我不知道该怎么做? – vedran
@vedran:如果你想编辑你的答案来提供你当前的一些代码,并且更全面地解释你将一个人从一种类型转换为另一种类型所要达到的目标,我可以给你一些更好的反馈。 – StriplingWarrior
一旦你创建了某种类型的实例(例如,Tutor
),那就是实例会有的运行时类型。这不能再改变了。
一些替代方案:
- 给
Student
一些构造函数接受另一个Student
实例,并拷贝了相关的字段。一个所谓的拷贝构造函数。这样,您可以根据您的Tutor
轻松创建一个新的Student
实例,然后使用它。 - 如果保留实际实例而不是创建一些副本很重要(也许您已经在整个地方保留引用),那么最好将角色与类分开。制作一些
FacultyMember
课程或将Student
和Tutor
转为角色。然后,您可以稍后更改FacultyMember
的角色。
您不能在Java中更改对象类型。可能最简单的方法是将Tutor的所有参数克隆到新的Student对象中。
您可以在Tutor上写一个像TutorToStudent()
这样的方法,并从您的导师中创建一个新学生。如果你演员,你会最终与对象仍然是一个导师。
你也可以考虑在这种情况下放弃继承,只是有一个标志表明这个学生是否是导师。
您可以使用与导师完全相同的信息创建一个新学生并丢弃原始对象。要么使用复制构造函数
Student(Student original)
要么使用Student toStudent()
方法这是一种快速和肮脏的方法。而不是让导师直接扩展一个学生,使
Tutor
具体的数据和行为为Decorator的。或者更好的是,使Tutor
和Student
包含所有人的People
对象的装饰器。这是做这件事的正确方法之一。充分利用
Tutor
和Student
为enum Type
和People
持有该领域,这是比上面更容易,但不易伸长,这真的取决于教师和学生之间的差异的性质。
有没有将他“转化”回学生,他是导师,而导师已经是学生的东西。
但是,通用化此对象的访问可能会有一些价值,因此您只能使用学生方法。在这里有几个Java的成语。
1)您可以在代码中专门使用Student API,但Tutor部分除外。
2)您可以为您的对象设置一个“toStudent/toTutor”方法,以便它们返回特定于该角色的对象。
//我的偏好 3)您可以使用接口。让Tutor和Student都是接口,并使用接口实现来构建对象。如果您使用最少的接口引用对象,而不是重量级继承模式,那么您的代码未来可能会更好地扩展。
我想,这个尖叫遏制和界面编程。
如何:
interface IStudent
{
String getName();
int getStudentId();
}
interface IFacultyMember
{
int getFacultyId();
}
class Student
implements IStudent
{
String name;
int id;
public String getName() { return name; }
public int getStudentId() { return id; }
}
class Tutor
implements IStudent, IFacultyMember
{
Student student;
int facultyId;
public Tutor (Student student, int facultyId)
{
this.student = student;
this.facultyId = facultyId;
}
public String getName() { return student.getName(); }
public int getStudentId() { return student.getStudentId(); }
public int getFacultyId() { return facultyId; };
}
这样一来,你的学生仍然是一个学生来说,即使它移动到导师的位置。当导师任期届满时,您只需GC导师记录。
另一方面,学生记录仍然可用于中央服务。
- 1. 是否有效将对象从基类转换为子类
- 2. Java中是否有可能将对象完全转换为其基类型?
- 3. 如何实现将超类对象转换为子类对象的效果?
- 4. 将超类的对象转换为子类
- 5. 将类对象转换为Java RDD
- 6. Java:超类数组对象分配有子类数组对象
- 7. 如何将对象从类转换为超类
- 8. 是否有可能将普通的json对象转换为字典类型?
- 9. 是否有可能将SimpleXML对象转换为PHP中的DOMDocument对象?
- 10. 将JSON对象转换为java类对象
- 11. 将类类型对象转换为Intptr
- 12. 是否有可能将cpp模型对象转换为NSData
- 13. 是否有可能将一个对象转换为System.Windows.DataObject.DataStore.DataStoreEntry?
- 14. 是否有可能将QVariants自动转换为Python对象?
- 15. 是否有可能使用@RequestParam从JSON转换为域对象
- 16. 将对象类型转换为Objective-C中的子类对象类型C
- 17. 是否可以将java类对象序列化为类文件?
- 18. 超类型变量是否可以引用子类对象?
- 19. 如何将类对象转换为通用对象类型?
- 20. 将对象[]转换为另一个对象[],有可能吗?
- 21. 是否有可能将匿名类从Java转换为JRuby?
- 22. 如何在java中将对象从超类获取到子类?
- 23. 是否有可能用主对象中的其他对象替换子对象?
- 24. 从子类访问超类对象
- 25. 模式:从轴对象转换Java类
- 26. 是否可以将类型转换为父类抽象类?
- 27. 为什么在Java中不允许将子类对象的子类集合转换为超类对象的超类集合?
- 28. 如何将超类对象值复制到子类对象值?
- 29. 是否有可能一个JSON转换为Java类对象。如果类不可用
- 30. 对象不能转换为类型“customObject”
可能你不应该使用继承来模拟这种关系。根据您的简短描述,您可能需要考虑创建一个Tutor包装器,它在施工时需要一名学生。然后,当合同完成时,您可以简单地让对包装的引用超出范围,并继续直接与Student实例一起工作。 –
你能否提供更多的背景给你的问题? imho它真的取决于你想要达到的目标。 也许增加一个'布尔isTutor;'成员或者干脆保留一个也是导师的学生列表就足够了。不需要仅仅因为可以用OO模式对所有东西进行建模。 – kritzikratzi
@kritzikratzi我喜欢你的评论“没有必要用OO建模所有东西......只是因为你可以”。不能同意更多! – corsiKa