Il polimorfismo è uno dei mattoni che compongono lo sviluppo di applicazioni con i linguaggi Object Oriented, si tratta è la capacità da parte di un oggetto di comportarsi in maniera diversa a seconda del contesto dove si trova ad operare.
Anche in ObjectiveC esiste il polimorfismo ma non viene utilizzato come in altri linguaggi tipo java o c#. Nella maggior parte dei linguaggi di programmazione ad oggetti, in genere è implementato in due modi diversi: attraverso l'ereditarietà o attraverso le interfacce. Con Objective C entrambi questi metodi sono supportati ma, sfruttando il fatto che si tratta di un linguaggio dinamico, possiamo implementare il polimorfismo anche in modo diverso. Esaminiamo prima l'implementazione 'classica', poi approfondiremo il secondo approccio.
Implementazione 'tradizionale'
Supponiamo di avere una classe ObjectiveC chiamata OperazioneMatematica
dichiarata nel modo seguente:(per ragioni didattiche abbiamo unificato il file di interfaccia ed implementazione degli esempi in un unica dichiarazione.)
#import <Foundation/Foundation.h>
@interface OperazioneMatematica : NSObject { }
-(void) doCalcolo:(float) num1 andNum:(float) num2;
@end
Implementazione:
#import "OperazioneMatematica.h"
@implementation OperazioneMatematica
-(void) doCalcolo:(float) num1 andNum:(float) num2 { }
@end
Nella classe definiamo un unico metodo di istanza doCalcolo
, l'implementazione del metodo non fa assolutamente nulla.
Adesso dichiaramo una seconda classe, OperazioneSomma
che deriva da OperazioneMatematica
che effettua l'override dell'unico metodo della classe base nel modo seguente:
#import <Foundation/Foundation.h>
#import "OperazioneMatematica.h"
@interface OperazioneSomma :OperazioneMatematica { }
-(void) doCalcolo:(float) num1 andNum:(float) num2;
@end
Implementazione:
#import "OperazioneSomma.h"
@implementation OperazioneSomma
-(void) doCalcolo:(float) num1 andNum:(float) num2
{
NSLog(@"Operazione eseguita somma: %f + %f = %f", num1, num2, num1 + num2);
}
@end
Dichiariamo adesso una terza classe OperazioneProdotto
anche essa derivante dalla prima classe e anche essa ridefinisce l'unico metodo della classe base:
#import <Cocoa/Cocoa.h>
#import "OperazioneMatematica.h"
@interface OperazioneProdotto : OperazioneMatematica { }
-(void) doCalcolo:(float) num1 andNum:(float) num2;
@end
Implementazione:
#import "OperazioneProdotto.h"
@implementation OperazioneProdotto
-(void) doCalcolo:(float) num1 andNum:(float) num2
{
NSLog(@"Operazione eseguita prodotto: %f x %f = %f", num1, num2, num1 * num2);
}
@end
Ora scriviamo la nostra funzione main
:
#import <Foundation/Foundation.h>
#import "OperazioneMatematica.h"
#import "OperazioneSomma.h"
#import "OperazioneProdotto.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
OperazioneMatematica *operazione = [[OperazioneProdotto alloc] init];
[operazione doCalcolo:4.5 andNum:3.0];
[operazione release];
operazione = [[OperazioneSomma alloc] init];
[operazione doCalcolo:4.5 andNum:3.0];
[operazione release];
[pool drain];
return 0;
}
Osservando il codice, l'oggetto operazione
è dichiarato come OperazioneMatematica
, ma successivamente viene assegnato prima ad una istanza di un oggetto OperazioneProdotto
, poi ad una istanza dell'oggetto OperazioneSomma
.
L'oggetto operazione
è polimorfico in quanto si comporta in modo diverso a seconda della istanza a cui viene assegnato anche se appartiene allo stesso tipo OperazioneMatematica
. Il risultato dell'esecuzione sarà:
2010-02-02 21:59:31.932 Polimorfismo[1368:a0f] Operazione eseguita prodotto: 4.500000 x 3.000000 = 13.500000 2010-02-02 21:59:31.934 Polimorfismo[1368:a0f] Operazione eseguita somma: 4.500000 + 3.000000 = 7.500000