Ho 2 classi una include methodA e l'altra include methodB. Quindi in una nuova classe ho bisogno di sovrascrivere i metodi methodA e methodB. Quindi, come posso raggiungere l'ereditarietà multipla nell'obiettivo C? Sono un po 'confuso con la sintassi.Eredità multipla Objective-C
risposta
Objective-C non supporta l'ereditarietà multipla e non è necessario. Usa composizione:
@interface ClassA : NSObject {
}
-(void)methodA;
@end
@interface ClassB : NSObject {
}
-(void)methodB;
@end
@interface MyClass : NSObject {
ClassA *a;
ClassB *b;
}
-(id)initWithA:(ClassA *)anA b:(ClassB *)aB;
-(void)methodA;
-(void)methodB;
@end
Ora hai solo bisogno di invocare il metodo sul relativo ivar. È più codice, ma semplicemente non c'è ereditarietà multipla come caratteristica del linguaggio nell'obiettivo C.
ne sai di protocolli, i protocolli è il modo per attuare l'ereditarietà multipla
-1: i protocolli sono * molto * diversi rispetto all'ereditarietà. – FreeAsInBeer
+1 "Per catturare somiglianze tra classi che non sono correlate gerarchicamente." https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html – pokstad
In questo caso, dove entrambi i metodi saranno sovrascritti, i protocolli faranno il trucco. In altri casi, quando si desidera utilizzare l'ereditarietà per riutilizzare il codice, i protocolli non sarebbero di aiuto. Tuttavia, di solito questo può essere risolto lasciando che le classi di superclassi ereditino le une dalle altre, o combinandole, di solito c'è un modo per farlo bene se una sottoclasse effettivamente condivide il codice con 2 classi. –
Questo è come mi codice singletonPattern come "genitore" Fondamentalmente ho usato una combinazione di protocollo e di categoria.
L'unica cosa che non posso aggiungere è un nuovo "ivar", tuttavia, posso spingerlo con l'oggetto associato.
#import <Foundation/Foundation.h>
@protocol BGSuperSingleton
+(id) singleton1;
+(instancetype)singleton;
@end
@interface NSObject (singleton) <BGSuperSingleton>
@end
static NSMutableDictionary * allTheSingletons;
+(instancetype)singleton
{
return [self singleton1];
}
+(id) singleton1
{
NSString* className = NSStringFromClass([self class]);
if (!allTheSingletons)
{
allTheSingletons = NSMutableDictionary.dictionary;
}
id result = allTheSingletons[className];
//PO(result);
if (result==nil)
{
result = [[[self class] alloc]init];
allTheSingletons[className]=result;
[result additionalInitialization];
}
return result;
}
-(void) additionalInitialization
{
}
Ogni volta che voglio una classe per "ereditare" questa BGSuperSingleton faccio e basta:
#import "NSObject+singleton.h"
e aggiungere @interface MyNewClass() <BGSuperSingleton>
Le categorie non sono ereditarietà multipla. Sono un modo di virare su metodi/funzioni a una classe già esistente. L'ereditarietà multipla consente a una terza classe di essere una combinazione di una o più classi (comprese le variabili). Mi piacciono le categorie. Le categorie sono molto utili. Ma NON sono eredità multiple. –
Ma una sottoclasse di UIViewController può anche "supportare", in questo caso, il modello singleton dovrebbe desiderare. –
Tecnicamente tutto NSManagedObject "può ora chiamare" [obj singleton]. Ho impostato quelli che desidero con il supporto del protocollo. Buono come eredità multipla in ogni caso. Questo è solo se voglio che la classe figlia supporti sia l'interfaccia che l'implementazione del genitore. Se solo l'implementazione, ovviamente, la composizione è la strada da percorrere. –
composizione è molto spesso un approccio migliore da prendere che eredità, soprattutto se si fai molte prove di unità sul codice. Offre molta più flessibilità in quanto puoi facilmente sostituire le implementazioni senza ridefinire la classe stessa. Particolarmente utile quando si desidera, ad esempio, scambiare ClassA e ClassB per oggetti mock. Anche a runtime, lo swapping delle implementazioni (ad esempio FTPFileStore vs LocalFileStore) diventa più pulito con la composizione. Ciò non significa che l'ereditarietà non abbia il suo posto, ma la necessità di ereditarietà multipla suggerirebbe di ripensare il mio design;) – d11wtq
Non lo capisco. Non hai bisogno di istanziare 'ClassA' e' ClassB'? Chiamare 'methodA:' su 'MyClass' in qualche modo chiama automaticamente' methodA: 'su' ClassA'? – zakdances
No, ma è comunque possibile condividere il comportamento attraverso il passaggio di messaggi, il modo in cui originariamente doveva funzionare OOP. Se non si passa immediatamente a pensare di aver bisogno di ereditarietà e invece di prendere in considerazione una soluzione utilizzando la composizione, scoprirai di iniziare a strutturare i tuoi programmi in un modo più gestibile. Ovviamente ObjC ha ereditarietà di base per i casi in cui è corretto utilizzarlo. – d11wtq