您对被允许这样做的怀疑是有根据的,但在这种特殊情况下,您还可以...
在对重写的严格子类型解释中,重写方法可以接受更通用类型的参数并返回更具体类型的值。
例如,使用 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;
你得到:
- (void) setMyBvalue:(C *)value;
- (C *) myBvalue;
并且setMyBvalue: 方法违反了严格的子类型化规则 - 将 C 实例强制转换为 B 实例,并且类型化规则说您可以传递 B,该方法需要一个 C,然后就会出现混乱。
但是在您的情况下,您要覆盖的属性是 readonly,因此没有设置器,也没有危险。