Ho due classi Studente e Tutor. Il tutor è fondamentalmente uno studente (il tutor estende lo studente) che ha facoltà. Una volta che il suo contratto è completo, torna ad essere solo uno studente. Quindi posso in qualche modo convertirlo al suo "precedente" rotolo di studenti?Java, è possibile 'convertire' oggetto da sottoclasse in oggetto dalla superclasse
risposta
Quello che vuoi veramente fare qui è usare composition and not inheritance. Conservare tutti gli oggetti come tipo Student
e quindi assegnare temporaneamente il comportamento di TutorRole
come richiesto a ciascuna istanza di Student
.
Con questo modello la classe Student
conterrà una proprietà (variabile membro) di tipo TutorRole
che è possibile aggiungere o rimuovere in fase di runtime. L'aggiunta di un metodo isTutor()
ti consentirà di scoprire se uno studente è un tutor al runtime in modo chiaro e conciso.
La classe TutorRole
incapsulerà il comportamento (cioè i metodi) di essere un 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
Un approccio alternativo è quello di avere una classe Tutor
contiene un riferimento a un oggetto Student
, ma dipende da come si sta andando ad essere l'interazione con lo studente e gli oggetti Tutor del modo in cui intorno si vuole codificare questo .
Puoi lanciare il Tutor come uno studente in modo che il codice lo tratta come tale al momento della compilazione, ma l'oggetto rimarrà un Tutor, in modo da chiamare qualsiasi metodi sostituiti farà sì che la versione della classe Tutor per essere chiamato.
L'unico modo per eseguire il tipo di "conversione" che stai cercando è creare un nuovo oggetto Studente e assegnargli tutte le proprietà del Tutor.
Poiché stai riscontrando che è necessario eseguire questa conversione, potresti voler ripensare alla struttura della classe. Ad esempio, forse sia gli studenti che i tutor dovrebbero essere solo persone e ogni persona può avere il ruolo di studente o insegnante.
Potresti per favore elaborare questo? Non sono sicuro di come farlo? – vedran
@vedran: se desideri modificare la tua risposta per fornire parte del tuo codice corrente e una spiegazione più completa di ciò che stai cercando di realizzare convertendo una persona da un tipo all'altro, posso darti un feedback migliore. – StriplingWarrior
Dopo aver creato un'istanza di un tipo (ad esempio, Tutor
), questo è il tipo di esecuzione che avrà l'istanza. Questo non può più essere cambiato.
Alcune alternative:
- Give
Student
qualche costruttore che accetta un altroStudent
istanza e copie sui campi pertinenti. Un cosiddetto costruttore di copie. In questo modo, potresti facilmente creare una nuova istanzaStudent
basata sul tuoTutor
e utilizzarla. - Se è importante conservare l'istanza effettiva piuttosto che crearne una copia (forse hai mantenuto i riferimenti dappertutto), sarebbe meglio separare il ruolo dalla classe. Crea una classe
FacultyMember
o qualcosa di simile e attiva i ruoliStudent
eTutor
. Quindi puoi modificare il ruolo diFacultyMember
in seguito.
Non è possibile modificare il tipo di oggetto in Java. Probabilmente il modo più semplice per ottenere il tuo modo è quello di clonare tutti i parametri da Tutor in un nuovo oggetto Studente.
Si potrebbe semplicemente scrivere un metodo come TutorToStudent()
su Tutor e creare un nuovo Studente dal proprio Tutor. Se lanci, finirai con l'oggetto che è ancora un Tutor.
Si potrebbe anche considerare di rinunciare all'ereditarietà in questo caso e basta avere una bandiera che indica se questo studente è o meno un Tutor.
Ma se avessi una collezione di Studenti, manterrebbe comunque il vecchio Tutor, non il nuovo Studente normale. – corsiKa
@glowcoder: vero ma questo vale per la maggior parte delle soluzioni che mantengono ancora la gerarchia dell'ereditarietà e tentano in qualche modo di trasformare il Tutor in uno Studente. Come ogni soluzione, non risolve tutti i casi e ovviamente occorrerà un codice aggiuntivo per giustificare casi come quelli che hai menzionato. –
sì, vale per le soluzioni che mantengono la gerarchia dell'ereditarietà. Ma è una buona pratica "Favorire la composizione sull'eredità". È molto meglio avere un ruolo 'Studente' e un ruolo' Tutor' e avere semplicemente un'istanza (o lista) di un ruolo (o ruoli, se si usa una lista). – corsiKa
È possibile creare un nuovo Studente con le stesse informazioni del Tutor e scartare l'oggetto originale. O con un costruttore di copie
Student(Student original)
o un metodoStudent toStudent()
Questo è il modo rapido e sporco.Invece di fare Tutor si estendono direttamente uno studente, rendendo i
Tutor
dati e comportamenti specifici in un Decorator. O, meglio ancora, rendere entrambi i decoratoriTutor
eStudent
di un oggettoPeople
che include tutti. Questo è uno dei modi migliori per farlo.Fai il
Tutor
eStudent
in unenum Type
e tenere premuto questo campo inPeople
, questo è più facile ma meno estensibili quanto sopra, in realtà dipende dalla natura delle differenze tra Tutor e Student.
Non esiste una cosa come "conversione" riportarlo a uno studente, è un tutore, e un tutor è già uno studente.
Tuttavia, potrebbe esserci qualche valore nel rendere generico l'accesso di questo oggetto, in modo da utilizzare solo il metodo studente. Ci sono diversi idiomi in Java per questo.
1) È possibile utilizzare l'API studente esclusivamente nel codice, ad eccezione della porzione Tutor.
2) È possibile avere un metodo "toStudent/toTutor" per gli oggetti, che consente loro di restituire oggetti specifici del ruolo.
// La mia preferenza 3) È possibile utilizzare le interfacce. Chiedi a Tutor e Student di essere interfacce e crea i tuoi oggetti utilizzando l'implementazione dell'interfaccia. Se fai riferimento a oggetti che usano interfacce minime, piuttosto che modelli di ereditarietà pesanti, il tuo codice probabilmente migliorerà in futuro.
Penso, questo grido di contenimento e programmazione dell'interfaccia.
ne dite di questo:
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; };
}
In questo modo, il vostro studente rimane uno studente, anche se si muove nella posizione di Tutor. Quando scade il termine del tutor, solo GC il record del tutor.
La documentazione dello studente, al contrario, sarà ancora disponibile nei Servizi centrali.
- 1. Uso della superclasse per inizializzare un oggetto sottoclasse java
- 2. Conversione da oggetto Java a sottoclasse
- 3. Sottoclasse - Argomenti da superclasse
- 4. Chiamare un metodo di sottoclasse dalla superclasse
- 5. Oggetto COM in Java, possibile?
- 6. subclass.prototype = new superclasse() vs. sottoclasse = new superclasse()
- 7. L'istanza è un "oggetto", ma la classe non è una sottoclasse di "oggetto": come è possibile?
- 8. Chiamare la superclasse da un costruttore sottoclasse in Java
- 9. Perché la conversione implicita è consentita dalla superclasse alla sottoclasse?
- 10. Java: Ottenere la sottoclasse da un elenco superclasse
- 11. è possibile convertire un oggetto dinamico in un ExpandoObject (C#)
- 12. JavaScript oggetto sottoclasse
- 13. È mai valido convertire un oggetto da una classe base in una sottoclasse
- 14. È possibile negare un oggetto java dalla serializzazione diverso da una parola chiave transitoria
- 15. Come convertire JSON in oggetto
- 16. Modifica dinamica della superclasse di un oggetto
- 17. Come convertire oggetto stringa in oggetto booleano?
- 18. Impostare un oggetto data Java da un oggetto DateTime Notes
- 19. Chiamare il metodo della sottoclasse dalla sua superclasse
- 20. Come "clonare" un oggetto in un oggetto sottoclasse?
- 21. Convertire file Java oggetto complesso a JSON
- 22. Un oggetto di una sottoclasse può accedere a un campo protetto di un altro oggetto di un'altra sottoclasse?
- 23. Java: restituzione della sottoclasse in modalità superclasse firma
- 24. Java: come convertire un oggetto File in un oggetto String in java?
- 25. È possibile leggere da un URL in un oggetto System.IO.Stream?
- 26. convertire da XML dinamico C# oggetto
- 27. È possibile serializzare automaticamente un oggetto C++?
- 28. Come convertire da stringa XElement oggetto
- 29. stringa convertire in datetime.time oggetto
- 30. Come convertire la stringa in oggetto Document DOM in java?
È possibile che non si debba utilizzare l'ereditarietà per modellare questa relazione. In base alla tua breve descrizione potresti prendere in considerazione la creazione di un wrapper Tutor che prende uno Studente in fase di costruzione. Quindi, una volta completato il contratto, è sufficiente lasciare che il riferimento al wrapper non rientri nell'ambito e continuare a lavorare direttamente con l'istanza di Student. –
puoi fornire un po 'più di contesto alla tua domanda? imho dipende davvero da cosa stai cercando di ottenere. magari aggiungendo un membro 'boolean isTutor;' o semplicemente mantenendo un elenco di studenti che sono anche tutor è sufficiente. non c'è bisogno di modellare tutto con schemi OO solo perché è possibile. – kritzikratzi
@kritzikratzi Amo il tuo commento "Non c'è bisogno di modellare tutto con OO ... solo perché puoi". Non potrei essere più d'accordo! – corsiKa