PDA

Visualizza la versione completa : Polimorfismo...


evil80
28-11-2002, 18:14
Ciao ragazzi,
ho bisogno di un po' di chiarimenti sul polimorfismo :

1- il polimorifismo è un termine generale per indicare concetti come l'overloading,sovraccarico degli operatori ?
2- il mio manuale di C# definisce il polimorfismo come la capacità mediante un riferimento alla classe base di potersi riferire sia alla classe base che alle sue classi derivate.

Quale delle 2 definizioni è corretta ?

Per sfruttare il secondo punto quindi l'unico modo è creare un array di tipo Classe base e poi associare alle sue varie celle classi derivate,in modo che per esempio ciclando l'array posso richiamare un metodo comune a tutte le classi ?

Insomma vorrei capire bene come sfruttare la "seconda parte" del polimorfismo,quello che ho detto io è giusto ?
E' l'unico vantaggio o ce ne sono altri ?

Grazie 1000 delle spiegazioni.

Come considerate C# ?

alka
28-11-2002, 18:58
Non ho esperienza in C#, ma abbastanza nella programmazione ad oggetti, dato che la sfrutto ogni giorno nello sviluppo con Delphi e mi sto avvicinando al mondo Java e, attraverso il linguaggio VB, anche a .NET.

La caratteristica del polimorfismo è quella che permette di introdurre un metodo all'interno di una classe affinchè esso possa essere "scavalcato" dalle classi che discendono da questa.

Esprimo meglio il concetto. Data una classe base, ogni classe che discende da essa ne eredita tutte le caratteristiche, inclusi metodi e proprietà. Questo significa che possiamo richiamare un metodo introdotto nella suddetta classe base sia avendo un'istanza di tale classe, sia avendo un'istanza di un'eventuale classe discendente.

Alcuni metodi, indicate con virtual (o dynamic) in Delphi e Overridable in VB .NET, possono essere "sovrascritti"; è possibile cioè aggiungere ad una classe base un'implementazione di un metodo che preceda, nella sua esecuzione, il metodo della classe base, richiamabile comunque all'interno della prima.

Prendo in esame (teorico) la classe che implementa all'interno di Delphi i controlli visuali: TControl. Tale classe introduce i concetti di dimensione (altezza e larghezza) e posizione (distanza dal margine sinistro e destro)...definisce insomma un'area all'interno della quale io posso tracciare qualcosa. Il metodo che esegue il tracciamento si chiama Paint...ma è vuoto!
Per creare un controllo visuale che tracci un rettangolo sullo schermo, basta creare una classe che discenda da TControl (ereditando la gestione delle dimensioni e della posizione...e tante altre funzionalità) in cui il metodo Paint venga ridefinito affinchè sostituisca quello della classe base. All'interno del nuovo metodo Paint, inserirò le istruzioni personalizzate necessarie al tracciamento del rettangolo.

Prendendo il tuo esempio, se hai un array generico di controlli visuali e richiami per ciascuno il metodo Paint, richiamerai sempre la versione "personalizzata" della classe discendente.

Spero di aver spiegato il concetto con sufficiente chiarezza. :bubu:

Il concetto di overloading è un'altra cosa: si tratta della definizione di più metodi all'interno di una classe che hanno lo stesso nome ma un diverso numero di parametri, eventualmente anche di tipi diversi. Il linguaggio che supporta questa funzionalità è in grado di eseguire l'implementazione che si adatta all'elenco dei parametri specificato in una chiamata al metodo...automaticamente.

Ciao! :ciauz:

biste
28-11-2002, 19:07
complimenti alka, la tua spiegazione mi è sembrata molto chiara :)

evil80
28-11-2002, 19:37
in due parole il concetto di polimorfismo si traduce nel concetto di prevalenza.

Esempio:



public abstract class MyBase
{
public abstract string Scrivi();
}


Poi derivo



public abstract class MyDerived:MyBase
{
public override string Scrivi()
{
return "Io prevalgo sul metodo della classe di base";
}

}


E' questo il polimorfismo ?
Questa è la sua vera ed unica definizione ?

Grazie

alka
28-11-2002, 19:53
L'esempio che hai fatto è corretto. Attenzione però alle classi e ai metodi astratti: è obbligatorio creare discendenze e farne l'override poichè la chiamata di un metodo, se astratto e non ridefinito, genera un errore!

Per la definizione di polimorfismo, in generale credo si possa dire sinteticamente che è la capacità di analizzare azioni (metodi) e caratteristiche (proprietà) di una entità (classe) ponendosi nel contesto dell'entità derivata (classe discendente) che si sta analizzando.

Magari qualcun altro avrà una definizione più azzeccata... :)

Ciao! :ciauz:

evil80
28-11-2002, 20:03
si,lo so ma il mio manuale consiglia se possibile di definire una classe astratta come classe base e definire i metodi opportunamente come astratti in modo da non potersi dimenticare di farne la prevalenza.
I metodi su cui invece non si deve prevalere per forza devono essere dichiarati come virtual mentre quelli su cui NON si deve prevalere sono definiti come sealed.

Allora il polimorfismo è la possibilità di richiamare i metodi di una determinata classe sapendo che per ogni classe varrà eseguita la propria versione del metodo ?

alka
28-11-2002, 20:36
Beh, io faccio sempre riferimento al mio modo di lavorare. Non so cosa avvenga in C#...può darsi che la definizione di classi astratte sia una pratica conveniente in quel linguaggio.

Per quanto riguarda la definizione che hai dato di polimorfismo, credo che sia fondamentalmente corretta. Il polimorfismo si esprime sia attraverso l'esecuzione del metodo appropriato in base alla classe con cui si ha a che fare, sia alla possibilità di implementare tramite codice quel meccanismo.

Ovviamente, la definizione che ne dò io viene formulata in base all'approccio pratico che applico nella scrittura del codice...magari qualche autorevole guida sulla programmazione ad oggetti ne dà una definizione formale diversa.

Ciao! :ciauz:

evil80
28-11-2002, 20:45
posso farti solo un'ultima domanda,visto che mi piace sempre avere un esempio pratico nelle cose che studio ?

Se tu dovessi scrivere un mailer,immaginalo pure molto semplice:
semplicemente si connette ad un db e prelevando i vari campi (mittente,destinatario,oggetto,messaggio) spedisce un messaggio...come imposteresti le classi ?

Insomma da quanto ho capito nella programmazione OOP bisogna disinteressarsi di "cosa fa il programmma",bisogna invece concentrare la propria attenzione su quali sono gli oggetti che lo compongono,giusto ?

Ora quali sono gli oggetti che compongono un mailer così semplice ?Come bisogna analizzare il problema ? Come si crea una struttura gerarchica di classi valida ?
Come devo sfruttare l'ereditarietà ?


Scusa se ti chiedo tutto questo ma come sempre dalla teoria alla pratica.....

Grazie

lelefante
28-11-2002, 21:05
A dire il vero il concetto di polimorfismo va piu' in la di quanto avete fin'ora espresso. Questo perche' gli esempi fatti consideravano un solo stadio di discendenza dalla classe base.
Considerate, tuttavia, una classe superiore, che chiamo parent, dalla quale faccio derivare tre classi distinte: child1, child2 e child3.
Nella classe parent esiste un metodo chiamato doSomething() non necessarriamente astratto. A loro volta le tre classi derivate ridefiniscono lo stesso metodo, ognuna in modo diverso dalle altre.
Ora durante l'esecuzione del programma io posso avere un riferimento ad un oggetto di tipo parent. Essendo le tre classi derivate una sottoclasse di parent, le loro istanze possono essere considerate oggetti di tipo parent a tutti gli effetti, di conseguenza il riferimento di cui parlavo prima puo' venire utilizzato anche per le sottoclassi child1, child2, e child3.
Durante l'esecuzione so che posso invocare il metodo doSomething() sul riferimento in mio possesso e so che verra' eseguito il metodo relativo alla classe alla quale mi sto riferendo: quindi se ho una classe child2 la chiamata parent.doSomething() eseguira' proprio il metodo doSomething() come ridefinito nella classe child2. Se invece il riferimento punta a un oggetto di tipo child3 verra' chiamato il metodo della classe child3, senza che cio' debba essere noto al momento della compilazione: questo e' il polimorfismo, e cioe' essere sicuri che a run-time venga eseguito il metodo definito nella classe appartenente all'oggetto puntato, e non alla sua superclasse.

L'esempio che si fa di solito e' quello della figura geometrica che contiene il metodo area(), che restituisce il valore dell'area. Le classi Triangolo, Quadrato e Cerchio ridefiniscono opportunamente questo metodo. A run-time, se ho un riferimento a una FiguraGeometrica, esso puo' essere utilizzato indifferentemente per un Triangolo, per un Quadrato o per un Cerchio. Il metodo area() eseguito sara' definito a run-time, a seconda che l'oggetto effetivamente referenziato sia un Triangolo, un Quadrato o un Cerchio.

Un ulteriore vantaggio del polimorfismo e' che posso introdurre una nuova figura ad esempio Pentagono, ridefinire opportunamente il metodo area() e inserirla nel progetto, senza aver bisogno di ricompilare tutto il resto, tanto funzionera' correttamente.

Spero di non essere stato eccessvamente lungo. Ciao

evil80
28-11-2002, 21:13
mi sembra che hai detto esattamente le stesse cose che avevamo già detto,comunque ogni opinione costruttiva è ben accetta

Loading