Mam dwie klasy Student i Tutor. Nauczyciel jest w zasadzie studentem (Nauczyciel przedłuża Studenta), który ma wydział ID. Po zakończeniu umowy powraca do bycia tylko studentem. Czy mogę jakoś przekonwertować go z powrotem na jego "poprzednią" rolkę ucznia?Java, czy można "przekonwertować" obiekt z podklasy do obiektu z nadklasy
Odpowiedz
Co naprawdę chcesz zrobić, to użyć composition and not inheritance. Zachowaj wszystkie swoje obiekty jako typ Student
, a następnie tymczasowo przypisz zachowanie TutorRole
, tak jak jest to wymagane do każdej instancji Student
.
Za pomocą tego projektu klasa Student
będzie zawierała właściwość (zmienną składową) typu TutorRole
, którą można dodać lub usunąć w czasie wykonywania. Dodanie metody isTutor()
pozwoli ci określić, czy Uczeń jest Nauczycielem w czasie wykonywania w sposób jasny i zwięzły.
Klasa TutorRole
będzie enkapsulować zachowanie (tj. Metody) bycia Tutorem.
/*
* 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
Alternatywnym podejściem jest posiadanie klasy Tutor
zawierają odniesienie do Student
obiektu, ale to zależy od tego jak masz zamiar być interakcja z uczniem i Opiekun obiektów na Którędy wokół chcesz kodować ten .
Możesz obsadzić Nauczyciela jako studenta, więc twój kod traktuje go jako takiego w czasie kompilacji, ale obiekt pozostanie Tutorem, więc wywołanie jakichkolwiek nadpisanych metod spowoduje wywołanie wersji klasy Nauczyciela.
Jedynym sposobem na zrobienie tego rodzaju "konwersji", której szukasz, jest stworzenie nowego obiektu Ucznia i nadanie mu wszystkich właściwości, które posiada Nauczyciel.
Po stwierdzeniu, że należy wykonać tę konwersję, może zajść potrzeba ponownego przemyślenia struktury klas. Na przykład, być może zarówno Uczniowie, jak i Nauczyciele powinni naprawdę być Osobą, a każda Osoba może mieć Role Ucznia lub Nauczyciela.
Czy mógłbyś to rozwinąć? Nie jestem pewien, jak to zrobić? – vedran
@vedran: Jeśli chcesz edytować swoją odpowiedź, aby podać część swojego obecnego kodu i pełniejsze wyjaśnienie, co próbujesz osiągnąć, przekształcając osobę z jednego rodzaju na inną, mogę dać ci lepszą opinię. – StriplingWarrior
Po utworzeniu instancji pewnego typu (na przykład Tutor
), jest to typ środowiska wykonawczego, który będzie mieć instancja. Tego nie można już zmienić.
Niektóre alternatywy:
- Daj
Student
jakiś konstruktor, który akceptuje kolejnąStudent
instancji i kopie nad odpowiednimi polami. Tak zwany konstruktor kopii. W ten sposób możesz łatwo utworzyć nową instancjęStudent
na podstawie swojejTutor
, a następnie użyć jej. - Jeśli ważne jest, aby zachować rzeczywistą instancję zamiast tworzyć kopię (być może zachowałeś referencje w całym miejscu), najlepiej oddzielić rolę od klasy. Zrób trochę klasy
FacultyMember
i zmieńStudent
iTutor
w role. Następnie możesz zmienić rolę później.
Nie można zmienić typów obiektów w Javie. Prawdopodobnie najłatwiejszym sposobem osiągnięcia tego jest sklonowanie wszystkich parametrów z Tutora do nowego obiektu Ucznia.
Możesz napisać metodę taką jak TutorToStudent()
na Nauczycielu i stworzyć nowego Ucznia ze swojego Nauczyciela. Jeśli rzucisz, skończysz z tym, że obiekt wciąż jest Tutorem.
Możesz również rozważyć rezygnację z dziedziczenia w tym przypadku i po prostu mieć flagę wskazującą, czy ten uczeń jest tutorem.
Ale gdybyś miał kolekcję Studentów, nadal trzymałby starego Tutora, a nie nowego zwykłego Studenta. – corsiKa
@glowcoder: Prawda, ale dotyczy to większości rozwiązań, które wciąż utrzymują hierarchię dziedziczenia i próbują jakoś zmienić Nauczyciela w Studenta. Jak każde rozwiązanie, nie rozwiązuje wszystkich przypadków, a dodatkowe kodowanie będzie oczywiście wymagane w przypadku takich przypadków jak wspomniane. –
Tak, to prawda, dotyczy rozwiązań, które utrzymują hierarchię dziedziczenia. Dobrą praktyką jest jednak "Przypisywanie kompozycji do dziedziczenia". Znacznie lepiej jest mieć rolę "Ucznia" i rolę "Nauczyciela" i po prostu mieć instancję (lub listę) roli (lub ról, jeśli używa się listy). – corsiKa
Możesz utworzyć nowego Ucznia z dokładnie tymi samymi informacjami co Nauczyciel i odrzucić oryginalny obiekt. Metoda konstruktora kopii
Student(Student original)
lubStudent toStudent()
To jest szybki i brudny sposób.Zamiast Opiekun bezpośrednio rozszerzyć student dokonywania
Tutor
konkretnych danych i zachowania w Decorator. Albo jeszcze lepiej, uczyń zarówno dekoratory obiektuTutor
obiektuPeople
, który obejmuje wszystkich. Jest to jeden z właściwych sposobów, aby to zrobić.Dokonać
Tutor
iStudent
wenum Type
i przytrzymaj to pole wPeople
, jest to łatwiejsze, ale mniej rozciągliwe niż wymienione powyżej, to naprawdę zależy od charakteru różnic między Nauczyciela i Ucznia.
Nie ma czegoś takiego jak "konwersja" go z powrotem do ucznia, jest on opiekunem, a tutor już jest studentem.
Jednak może istnieć pewna wartość w generalizacji dostępu do tego obiektu, więc używasz tylko metody ucznia. W języku Java jest kilka idiomów.
1) Możesz używać interfejsu API Studenta wyłącznie w swoim kodzie, z wyjątkiem części Nauczyciela.
2) Możesz mieć metodę "toStudent/toTutor" dla swoich obiektów, która pozwala im zwracać obiekty, które są specyficzne dla danej roli.
// Moje preferencje 3) Możesz używać interfejsów. Niech zarówno Nauczyciel, jak i Uczeń będą interfejsami i będą budować obiekty za pomocą implementacji interfejsu. Jeśli odwołasz się do obiektów używających minimalnych interfejsów, a nie do wzorców heavyweight dziedziczenia, twój kod będzie prawdopodobnie lepiej skalowany w przyszłości.
Myślę, że to krzyczy, powstrzymywanie i programowanie interfejsu.
Jak o tym:
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; };
}
ten sposób swoją Student pozostaje student, nawet jeśli porusza się w pozycji nauczyciela. Kiedy kończy się okres Tutora, po prostu GC jest rekordzistą nauczyciela.
Z drugiej strony, zapisy studentów nadal będą dostępne w Centralnych Usługach.
- 1. java, zainicjować podklasy z nadklasy
- 2. jak użyć zmiennej z nadklasy do podklasy?
- 3. Jak wywołać metodę nadklasy obiektu Objective-C z innego miejsca?
- 4. metody nadklasy wrócić typu podklasy w Swift
- 5. Dynamiczna zmiana nadklasy obiektu
- 6. Java: Uzyskiwanie podklasę z nadklasy listy
- 7. Uzyskiwanie nazwy obiektu z obiektu klasy podklasy NSMangedObject
- 8. Jak przekonwertować obiekt Java Data na obiekt JRuby Time?
- 9. Java: Jak przekonwertować obiekt File na obiekt String w java?
- 10. javascript przekonwertować z epoki ciąg do obiektu Date
- 11. przekonwertować z JSON do obiektu kolekcji
- 12. Java przekonwertować obiekt tablicy na int tablicy
- 13. Przenoszenie obiektu python/django z modelu nadrzędnego do potomka (podklasy)
- 14. Czy można uzyskać liczbę odwołań do obiektu?
- 15. Czy można uzyskać wszystkie podklasy klasy?
- 16. można przekonwertować obiekt dynamiczny na obiekt ExpandoObject (C#)
- 17. Java - Czy można rozszerzyć wszystkie podklasy klasy o jedną klasę?
- 18. Jak przekonwertować obiekt ścieżki Hadoop na obiekt pliku Java
- 19. Java: Dostęp do podklasy bez dostępu do pakietów
- 20. Nie można uczynić statycznych odniesienie do ogólnych podklasy (Java)
- 21. Czy można wykryć, czy obiekt jest tymczasowy z funkcji członka?
- 22. Java: nie można uzyskać dostępu do chronionego członka nadklasy w rozszerzającej podklasie
- 23. W języku java, czy możemy przekazać nadklasę Obiekt do odwołania do podklasy?
- 24. Wywołanie awakeFromNib z nadklasy
- 25. Wywołanie metody z nadklasy Podklasa - JavaScript
- 26. Czy inicjalizator dla nadklasy zwraca konkretną podklasę?
- 27. Jak przekonwertować z pliku binarnego na relokatowany obiekt z powrotem?
- 28. czy mimo to można przekonwertować z Double do BigInteger?
- 29. Jak przekonwertować ciąg do obiektu DOM Document w java?
- 30. Tworzenie podklasy z różnymi własności podklasy
Możliwe, że nie powinieneś w ogóle używać dziedziczenia do modelowania tego związku. Opierając się na twoim krótkim opisie, możesz rozważyć utworzenie opakowania Tutora, które zabiera Studenta w czas budowy. Następnie, gdy umowa zostanie zakończona, możesz po prostu pozwolić, aby odwołanie do opakowania odpadło z zakresu i kontynuować pracę z instancją Ucznia bezpośrednio. –
czy możesz podać nieco więcej kontekstu do swojego pytania? imho to naprawdę zależy od tego, co próbujesz osiągnąć. być może dodanie członka 'boolean isTutor;' lub po prostu trzymanie listy studentów, którzy są również nauczycielami jest wystarczające. nie ma potrzeby modelowania wszystkiego za pomocą wzorców OO tylko dlatego, że możesz. – kritzikratzi
@kritzikratzi Kocham twój komentarz "Nie trzeba modelować wszystkiego z OO ... tylko dlatego, że możesz". Nie można się zgodzić na więcej! – corsiKa