2010-03-29 4 views
1

Je veux créer des classes de voitures, de véhicules et d'avion avec les propriétés suivantes:iPhone - méthode d'initialisation d'une classe abstraite

  • Voiture et avion sont tous les deux sous-classes de véhicules.
  • Car et Airplane ont tous deux une méthode initWithString.
  • Les chaînes d'entrée acceptables pour les méthodes initWithString et de son avion de voitures ne se chevauchent pas.
  • Le véhicule est "presque abstrait", en ce sens que toute instance initialisée doit être une voiture ou un avion.
  • Il est possible de passer une chaîne dans le véhicule et retourner une instance de voiture, une instance de l'avion, ou nul, selon la chaîne d'entrée.

Tout modèle de conception particulière, je préférerais? En particulier pour les méthodes initWithString et/ou newVehicleWithString de Vehicle.

Répondre

4

Qu'est-ce que vous avez besoin est le modèle « de cluster de classe ». Votre méthode Vehicle initWithString: pourrait ressembler à ceci:

- (id) initWithString:(NSString *)mode { 
    // note that we don't call [super init] in a class cluster. 
    // instead, we have to release self because it's an unwanted Vehicle instance 
    [self release]; 
    if([mode isEqualToString:@"wheels"]) { 
    return [[Car alloc] initWithString:@"wheels"]; 
    } 
    if([mode isEqualToString:@"wings"]) { 
    return [[Airplane alloc] initWithString:@"wings"]; 
    } 
    return nil; //alternately, raise NSInvalidArgumentException 
} 
+0

Je pense qu'il est utile de noter que dans ce cas, il serait probablement beaucoup plus efficace de surcharger alloc et de renvoyer une instance singleton spéciale qui alloue et initialise la classe correcte et la retourne. –

+1

C'est vrai, mais cela ressemble beaucoup à une optimisation prématurée. – codewarrior

+0

Il semble que de nos jours tout le monde doive aller à l'extrême. Maintenant, les gens ne pensent même pas à des solutions simples quand il y a une opportunité très claire et facile à «optimiser». Dans votre cas, vous créez et jetez des objets 100% du temps. Nous avons besoin d'équilibre, les gens :) Dans ce cas, il serait plus propre et plus correct de toute façon - alloc est également où les clusters de classe sont créés, pas dans init. –

0

Se référant à une sous-classe d'une superclasse n'est pas une bonne idée.

Si vous avez vraiment à ce faire, vous devriez au moins aller avec une méthode de classe comme vehicleWithString:.

En fait, je doute que l'autre approche (en utilisant vehicle initWithString: pour créer des instances de voiture ou d'avion) ​​fonctionnerait.

+1

La chose superclasse-faisant référence à la sous-classe est de savoir comment les clusters de classe travaillent tout au long de cacao. – Chuck

+0

Au contraire! C'est un modèle de conception appelé "clusters de classe", où '' '' initWithString: Vehicle '' décide quelle sous-classe renvoyer une instance de. Ce modèle est utilisé dans Cocoa, en particulier par NSString. – codewarrior

+0

C'est précisément pourquoi j'aime SO, merci. Cependant, pour autant que je sache, les sous-classes des classes de Cocoa sont toutes privées. Je pense toujours que l'utilisation de ce modèle avec des sous-classes publiques est quelque peu dangereuse. –

Questions connexes