在 Objective C 中,我如何让子classes 继承静态 class 变量,如果设置这些变量,则不会更改所有子项的变量值?

In Objective C, how can I have subclasses inherit static class variables that, if set, won't change the variable's value for all children?

在 Objective C 中,如何让子classes 继承静态 class 变量,如果设置了这些变量,则不会更改所有子项的变量值?

假设我有抽象的 class 汽车。它有一个静态 BOOL,"isSportsCar",我们设置为零。

然后在subclassSportsCar的init方法中,我们设置isSportsCar = YES。

我的目标是让 SportsCar 的所有实例都将 return "YES" 来自方法 "isSportsCar"(return 是静态 BOOL 的值)。

问题是 Car 的所有其他子class,例如 LuxuryCar 和 Limousine,现在都 return 来自 "isSportsCar"。

我想避免必须在所有子classes 中声明 isSportsCar 方法。

但是我如何创建一个 class 变量,让每个子 class 都有自己的变量实例?

不要使用静态变量执行此操作。使用 class 方法。所以在抽象基础 class Car 你有:

Car.h:

+ (BOOL)isSportsCar;

Car.m:

+ (BOOL)isSportsCar {
    return NO;
}

那么在你的 SportsCar class 你有:

运动Car.m:

+ (BOOL)isSportsCar {
    return YES;
}

那么只有从 SportsCar 继承的 class 才会 return YES.

你不能。至少不是静态变量。

静态变量的想法是它们是 classes 本身的值,而不是实例。因此从逻辑上讲,所有实例都有一个值,无论这些实例是定义变量的 class 实例,还是 subclass 实例。要具有不同的值,您需要创建实例变量或属性。然后值可以不同。

例如,您可以定义只读属性并将 getter 编码为 return 硬编码值,如下所示:

@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

但是从你所说的上下文来看,我怀疑你想知道你在代码中处理 SportsCar 的时间。像这样:

if (car.isSportsCar) {...}

如果你有各种类型的卡可以是跑车就好了,都运行一样class。但是如果你正在创建不同的 classes,你可能想要自己保存代码并简单地测试 class 本身:

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

即使您随后添加从 SportsCar class 派生的 Bugatti class,这仍然有效。这一切都取决于您要实现的目标。

我最后的建议是记住 KISS 原则并避免创建有效复制其他数据的变量或属性。

你的解决方案失败只是因为你使用了静态变量。如果您在基础 class 上定义了实例变量或 属性,那么您的方案有效。

你的基地 Car class 做它现在做的事 - 在它的 init 方法中将实例 variable/property isSportsCar 设置为 NO . Car 的任何实例,或其任何子 classes,现在都有一个 属性 isSportsCar,其中 returns NO.

你的 subclass init 方法 SportsCar 首先使用 [super init] 调用它的 superclass 的 init 方法 - 这将 isSportsCar 设置为 NO,然后进行初始化并将 isSportsCar 设置为 YES。现在对于 SportsCar 的任何实例或其任何子 classes,isSportCar 将 return YES.

如果你对 isSportsCar 使用 属性,你可以在 public 头文件中将其声明为 readonly,并在私有文件中声明为 readwrite头文件仅 subclasses 导入。这样 subclasses 可以设置 属性 但所有其他人只能读取它。

仅当值可能更改时才需要使用 property/instance 变量。在 isSportsCar 的情况下,不太可能针对特定的 class 进行更改。在那种情况下,您可以只使用一个实例方法,根据需要在 subclasses 中覆盖。所以 Car 将包含:

- (BOOL) isSportsCar { return NO; }

SportsCar将包含:

- (BOOL) isSportsCar { return YES; }

与 属性 方法一样,继承处理 Car 或其任何子 class 的其余部分和实例 except SportsCar, return NO;而 SportsCar 及其任何子 class 的实例 return YES.

HTH