在 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
在 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