我有兩個類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