Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Java - Polimorfismo, upcasting e dynamic binding
Forum - Java - Polimorfismo, upcasting e dynamic binding

Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 18:27
Venerdì, 23/01/2015
Ieri; ultima lezione di sistemi del semestre, il professore punta a concludere un infarinatura generale d'ingegneria del software mediante la spiegazione di Java. Ultimi argomenti override, upcasting e polimorfismo. Un ottima occasione per fare un ripasso generale di java, un linguaggio che mi è capitato di usare molto di rado, ripreso in mano per la voglia di sviluppare per Android.
Dopo la spiegazione del polimorfismo arriva a farci soffermare su un punto che contraddistingue i linguaggi con paradigma orientato agli oggetti da altri tipi di paradigma come quello strutturato del C, sto parlando del dynamic binding. Strumento che sostituisce il binding classico di funzioni nei linguaggi che supportano il polimorfismo.
Ha spiegato che il dynamic binding deve portare un metodo che supporta un argomento classe madre a saper interpretare quale siano i "sotto-metodi" da richiamare in runtime.
Ora nasce nella mia testa una domanda, per porla al meglio lasciate che vi esponga un esempio.
Codice sorgente - presumibilmente Java

  1. public class Computer
  2. {
  3.     ...
  4.     public byte Clock() {...}
  5.     ...
  6.     public static void PrintClock(Computer comp) { System.out.println(comp.Clock()); }
  7. }
  8. public class Microcontroller extends Computer
  9. {
  10.     ...
  11.     public byte Clock() {...}
  12.     ...
  13. }
  14. public class Laptop extends Computer
  15. {
  16.     ...
  17.     public byte Clock() {...}
  18.     ...
  19. }
  20. public class Process
  21. {
  22.     public static void Main(string[] args)
  23.     {
  24.         Laptop l = new Laptop();
  25.         Computer c = new Computer();
  26.         Microcontroller m = new Microcontroller();
  27.  
  28.         Computer.PrintClock(l);
  29.         Computer.PrintClock(c);
  30.         Computer.PrintClock(m);
  31.     }
  32. }


Tre classi, una madre e due che la estendono, piu ovviamente la classe base del programma. La domanda ora è molto semplice, quando vado a creare un istanza di un oggetto la vm si occupa di allocare lo spazio di memoria necessario alla classe per contenere i dati prefissati, quindi avrò 3 oggetti che occupano una quantità prestabilita di memoria: Computer x parole, Microcontroller x+y parole e Laptop x+z parole, tutte che presentano un implementazione del metodo Clock.
Quando vado ad eseguire il metodo statico PrintClock, viene eseguito l'upcasting delle istanze di Microcontroller e Laptop, quindi questi due oggetti vengono trattati come delle istanze di Computer di x Parole, la parte aggiuntiva di memoria y e z non viene più considerata all'interno del metodo. Ma questo solleva un dilemma, come fa la virtual machine a eseguire il dynamic binding al giusto metodo Clock visto che con l'upcasting ha perso il riferimento alla classe di cui sono istanza gli oggetti trattati? Qual'è il sistema che usa?
Il professore non mi ha saputo rispondere, trattandosi di una domanda molto tecnica e non strettamente inerente al suo corso. Mi ha suggerito di cercare in rete facendomi notare però, che un normale manuale di Java potrebbe non rispondere a questa domanda e in caso di fallimento avrei potuto riproporla a lui stesso, che avrebbe cercato di trovare la spiegazione di questo funzionamento fondamentale dei linguaggi OOP, come il mio adorato C#(che però non mi aveva mai fatto pensare a come effettivamente si comporti in caso di polimorfismo).
Come supposto dal professore non sono riuscito a trovare una risposta, i manuali tendono giustamente a tenersi su un livello molto alto(visto che la funzione dei linguaggi come il java è proprio quella). Quindi prima di riproporre la domanda a lui, chiedo a voi, sono abbastanza convinto che qualcuno conosca la risposta a questa domanda.
Aspetto una vostra spiegazione, grazie a chiunque vorrà provare a esporre una spiegazione e buona giornata ;-)

PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 18:46
Venerdì, 23/01/2015
Testo quotato

Postato originariamente da Roby94:
Ma questo solleva un dilemma, come fa la virtual machine a eseguire il dynamic binding al giusto metodo Clock visto che con l'upcasting ha perso il riferimento alla classe di cui sono istanza gli oggetti trattati? Qual'è il sistema che usa?



No, non ha perso il riferimento.

Immagina un pò il layout in memoria:

Testo quotato


Computer:
  -- vtable : {
     -- Clock: Clock_computer
  }
  -- Clock_computer
  -- PrintClock



Testo quotato


Microcontroller:
  -- vtable : {
     -- Clock: Clock_microcontroller
  }
-- Clock_computer
-- PrintClock
-- Clock_microcontroller




vtable fa riferimento alla virtual method table (la cui implementazione dipende da linguaggio a linguaggio, ma l'idea è la stessa per tutti). http://en.m.wikipedia.org/wiki/Virtual_method_table

Quando fai un upcast, la vtable mantiene un riferimento al metodo della sotto-classe (anche se viene invocata tramite il tipo della classe base).

Testo quotato


(Computer)microcontroller:
  -- vtable : {
     -- Clock: Clock_microcontroller
  }
-- Clock_computer
-- PrintClock
-- Clock_microcontroller



Se conosci MIPS Assembly puoi guardare questo programma per avere un'idea di come il polimorfismo viene implementato a basso livello: http://www.pierotofy.it/pages/sorgenti/dettagli/18486-Impl ...

Edit: aggiornato per correggere alcune informazioni.

Ultima modifica effettuata da pierotofy il 23/01/2015 alle 19:51


Il mio blog: https://piero.dev
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 19:03
Venerdì, 23/01/2015
Grazie Piero per la tua velocità.
Ma senti dopo l'upcasting tu segni che clock non è raggiungibile è pure è quello il metodo che viene richiamato, cosi a petto come lo hai scritto te sembra che invece il metodo che si possa richiamare sia solo quello descritto nella classe computer.

Mi dispiace ma ho studiato un unico assembly molto semplificativo derivato dall'Intel x86.

PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 19:55
Venerdì, 23/01/2015
Ho fatto un pò di confusione, ora ho corretto.

Se cerchi un pò di informazioni sull'uso delle virtual method table troverai ulteriori spiegazioni.


Il mio blog: https://piero.dev
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 17:37
Lunedì, 26/01/2015
Da quello che ho capito (da un riferimento C# trovato) la vtable non è altro che una simil-struttura istanziata con la classe che contiene delle informazioni strutturali della classe, tra cui un puntatore di riferimento alla classe da cui è stata istanziata. Il sistema è circa questo? Ho capito bene?

PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 18:53
Lunedì, 26/01/2015
Si.


Il mio blog: https://piero.dev
PM Quote