你对被允许这样做的怀疑是有根据的,但是在这个特别的如果你没事的话...
在重写的严格子类型解释中,重写方法可以接受更通用类型的参数并返回更具体类型的值。
例如,使用 Objective-C,给出:
@interface A : NSObject { ... }
@interface B : A { ... }
@interface C : B { ... }
和B中的方法M:
- (B *) M:(B *)arg { ... }
那么在严格子类型下的 C 类中,可以使用以下方法在 C 类中覆盖它:
- (C *) M:(A *)arg { ... }
这是安全的,因为如果您有一个对明显 B 对象的引用:
B *bObj = ...;
然后方法 M 调用:
B *anotherBObj = [bObj M:[B new]];
那么是否bObj
实际上是 B 或 C,调用类型正确 - 如果它是 C 对象,那么参数是 B 就可以了,因为它也是 A,结果是 C 就可以,因为它也是 B。
这让我们想到,不完全的,您的财产;在 Objective-C 中,属性只是两个方法的简写:
@property B *myBvalue;
是以下形式的简写:
- (void) setMyBvalue:(B *)value;
- (B *) myBvalue;
如果该属性在 B 中声明,并且您在类 C 中使用 C 值属性覆盖它:
@property C *myBvalue;
you get:
- (void) setMyBvalue:(C *)value;
- (C *) myBvalue;
和方法setMyBvalue:
违反了严格的子类型规则 - 将 C 实例转换为 B 实例,并且类型规则规定您可以传递 B,该方法需要 C,并且可能会发生混乱。
However在你的情况下,你要重写的属性是readonly
,所以没有二传手,也没有危险。