2016-06-09 10 views
0

Wie können in Objective C Unterklassen statische Klassenvariable erben, die den Wert der Variablen für alle untergeordneten Elemente nicht ändern?Wie können in Objective C Unterklassen statische Klassenvariable erben, die den Wert der Variablen für alle untergeordneten Elemente nicht ändern?

Lets sagen, ich habe abstrakte Klasse Auto. Es hat eine statische BOOL, "isSportsCar", die wir auf Null setzen.

Dann in der InS Methode von SportsCar der Unterklasse setzen wir isSportsCar = YES.

Mein Ziel war, dass alle Instanzen von SportsCar "YES" von der Methode "isSportsCar" zurückgeben (die den Wert des statischen BOOLs zurückgibt).

Das Problem ist, dass alle anderen Unterklassen von Auto, wie LuxuryCar und Limousine, jetzt alle JA von "isSportsCar" zurückgeben.

Ich möchte vermeiden, die IsSportsCar-Methoden in allen Unterklassen zu deklarieren.

Aber wie kann ich eine Klassenvariable machen, in der jede Unterklasse eine eigene Instanz dieser Variable hat?

+1

Nur um Ihre Frage ein wenig klarer zu machen, können Sie ein Code-Snippet bereitstellen, das das * gewünschte Verhalten * zeigt? Wie ein Komponententest, der das Verhalten der Implementierung, nach der Sie in Ihrer Frage fragen, überprüft? –

+0

Objective-C-Klassen haben (und können nicht) Klassenvariablen, daher sollte diese Variable wahrscheinlich eine Instanzvariable sein, die in der 'init'-Methode festgelegt ist. – mipadi

+0

* Ich möchte vermeiden, dass die isSportsCar-Methoden in allen Unterklassen deklariert werden müssen. * Wahrscheinlich möchten Sie es vermeiden, eine Instanzmethode für alle Unterklassen zu definieren, weil Sie sie an der Basisklasse deklarieren können. Warum möchten Sie es jedoch vermeiden? Was macht das schlechter, als eine Variable für alle Unterklassen zu setzen? –

Antwort

2

Verwenden Sie keine statische Variable. Verwenden Sie eine Klassenmethode. So in der abstrakten Basisklasse Car Sie haben:

Car.h:

+ (BOOL)isSportsCar; 

Car.m:

+ (BOOL)isSportsCar { 
    return NO; 
} 

Dann in Ihrem SportsCar Klasse Sie haben:

SportsCar. m:

+ (BOOL)isSportsCar { 
    return YES; 
} 

Dann werden nur von SportsCar geerbte Klassen YES zurückgegeben.

+0

Dies ist die richtige Antwort, da die Frage spezifiziert, dass es eine * Klasse * Variable sein musste. Und eine coole Sache in Objective C ist, dass Sie die Punktsyntax verwenden können, wie Sie schreiben können: 'if (Limousine.isSportsCar) {...}'. Wenn ich eine Pseudo-iVar daraus machen möchte, kann ich eine andere Methode haben: '- (BOOL) isSportsCar {return [[Selbstklasse] performSelector: @selector (isSportsCar)]; } 'Ich könnte sogar überschreiben, was dies zurückgibt, wenn' isSoupedUpAndPimpedOut' wahr ist: D – CommaToast

1

Sie können nicht. Zumindest nicht mit statischen Variablen.

Die Idee der statischen Variable ist, dass sie Werte auf den Klassen selbst sind, nicht die Instanzen. Logischerweise gibt es für alle Instanzen einen Wert, unabhängig davon, ob diese Instanzen zu der Klasse gehören, in der die Variable definiert wurde, oder zu Instanzen von Unterklassen. Um unterschiedliche Werte zu haben, müssen Sie Instanzvariablen oder Eigenschaften erstellen. Dann kann der Wert anders sein.

Zum Beispiel könnten Sie Nur-Lese-Eigenschaften und Code einen Getter zurückzukehren, um eine hartcodierte Wert wie folgt definieren:

@interface Car:NSObject 
@property (nonatomic, assign, readonly, getter=isSportsCar) BOOL sportsCar; 
@end 

@implementation Car 
-(BOOL) isSportsCar { 
    return NO; 
} 
@end 

@interface SportsCar:Car 
@end 

@implementation SportsCar 
-(BOOL) isSportsCar { 
    return YES; 
} 
@end 

jedoch aus dem Rahmen dessen, was Sie sagen, vermute ich, Sie bekannt möchten, wenn Sie sind Umgang mit einem SportsCar in Ihrem Code. Etwas wie folgt aus:

if (car.isSportsCar) {...} 

Das ist in Ordnung, wenn Sie verschiedene Arten von Karten haben, die Sportwagen sein kann, die alle mit der gleichen Klasse ausgeführt wird.Aber wenn Sie verschiedene Klassen erstellen, sollten Sie sich den Code speichern und einfach testen Sie die Klasse selbst:

if ([car isKindOfClass:[SportsCar class]]) {...} 

Auch wenn Sie dann eine Bugatti Klasse aus einer SportsCar Klasse abgeleitet hinzufügen, wird dies immer noch funktionieren. Alles läuft darauf hinaus, was Sie erreichen wollen.

Meine letzte Empfehlung wäre, sich an das KISS-Prinzip zu erinnern und das Erstellen von Variablen oder Eigenschaften zu vermeiden, die andere Daten effektiv duplizieren.

1

Ihre Lösung funktioniert nur, weil Sie eine statische Variable verwendet haben. Wenn Sie für die Basisklasse eine Instanzvariable oder eine Eigenschaft definiert haben, funktioniert Ihr Schema.

Ihre Basis Car Klasse tut, was es jetzt tut - setzt die Instanz-Variable/Eigenschaft isSportsCar-NO in seiner init Methode. Jede Instanz von Car oder einer ihrer Unterklassen hat jetzt eine Eigenschaft isSportsCar, die NO zurückgibt.

Die init Methode Ihrer Unterklasse SportsCar ersten Anrufe die init Methode seiner übergeordneten Klasse [super init] mit - die isSportsCar-NO setzt, dann tut ihr jetzt initialisiert und setzt isSportsCar-YES. Für jede Instanz von SportsCar oder einer seiner Unterklassen wird isSportCarYES zurückgeben.

Wenn Sie eine Eigenschaft für isSportsCar verwenden, können Sie es als readonly in der öffentlichen Headerdatei und als readwrite in einer privaten Headerdatei nur Unterklassen importieren. Auf diese Weise können Unterklassen die Eigenschaft festlegen, aber alle anderen können sie nur lesen.

Die Verwendung einer Eigenschaft/Instanzvariable ist nur erforderlich, wenn sich der Wert ändern kann. Im Fall von isSportsCar ist es unwahrscheinlich, dass sich dies für eine bestimmte Klasse ändert. In diesem Fall können Sie einfach eine Instanzmethode verwenden, die wie in Unterklassen erforderlich überschrieben wird. So würde Car enthalten:

- (BOOL) isSportsCar { return NO; } 

und SportsCar würde enthalten:

- (BOOL) isSportsCar { return YES; } 

wie mit der Eigenschaft Ansatz Erbe übernimmt den Rest und Instanzen von Car oder einer ihrer Unterklassen außerSportsCar, Rückkehr NO ; während Instanzen von SportsCar und einer ihrer Unterklassen YES zurückgeben.

HTH