如果我将子类实例分配给类型为父类的属性,是否保留了子类属性?

时间:2016-03-28 18:17:28

标签: objective-c oop polymorphism

我有一个加载数组的Feed:

PhotoStatus个对象

Status个对象 - ViewCommentsViewController

的子类

当用户点击Feed中的状态时,它会将他们带到@property (nonatomic,strong) Status *status; ,其中必须设置以下属性才能使视图控制器正常工作:

  ViewCommentsViewController.status=photoStatus;  

如果我通过/分配:

photoStatus

我能否可靠地保留photoStatus *revertedPhotoStatus=status;的子类属性如何?也许在我的视图控制器中执行photoStatus之类的操作,或者尝试做什么的正确方法是什么?我不想拥有多个视图控制器类,我也不想走这条草率路线同时拥有status&我的ViewCommentsViewController中的Status属性,那么如何可靠地允许加载多个类型的内容,这些内容都是{{1}}的子类?

3 个答案:

答案 0 :(得分:3)

  

我可以可靠地保留photoStatus的子类属性吗

是的,这只是自动发生。它被称为多态:它就是它的东西,而不是你碰巧输入它的东西。因此,如果您将一个实际的PhotoStatus对象分配给一个类型为Status的变量,它仍然是一个PhotoStatus。这种机制绝对至关重要;没有它,子类实例将不会非常有用!

但是,请注意,为了将您的状态类型对象视为作为PhotoStatus对象,如果它实际上是它的内幕,则需要将其转换为PhotoStatus宾语。如果你这样做并且发生了PhotoStatus对象,那么当PhotoStatus消息被发送到实际上不是PhotoStatus的对象时,你可能会发生崩溃。

答案 1 :(得分:3)

在最好的世界中,你不需要测试什么类的东西。相反,接收该对象的类将声明一个指向实现所有必要方法的基类的指针。

实现会有所不同,但在这种情况下,ViewCommentsViewController可以对任何类型的Status进行一致调用,并且知道方法存在。

构建事物以确保这一点的另一种方法是使用协议。这会使你的声明像@property (nonatomic,strong) id<StatusProvider> status;

我经常输入isKindOfClass以表达自己是一种纯粹主义者,但在可能的情况下使用干净的方法会很好。

答案 2 :(得分:1)

如果您打算使用Status类而不是PhotoStatus中定义的方法,则需要检查返回对象的类。要做到这一点,你通常会沿着这些方向做点什么:

Status *status = viewCommentsViewController.status;
if ([[status class] isSubclassOfClass: [PhotoStatus class]])
{
    PhotoStatus *photoStatus = (PhotoStatus *) status;
    // Handle photoStatus.
}
else
{
    // Handle the other case.
}

如果您想在呼叫站点保存几行,可以添加以下访问器:

@implementation Status
- (PhotoStatus *) asPhotoStatus
{
    return nil;
}
@end

@implementation PhotoStatus
- (PhotoStatus *) asPhotoStatus
{
    return self;
}
@end

然后只需致电

[[viewCommentsViewController.status asPhotoStatus] doSomething];

编辑:从Xcode 4.2开始,向nil发送消息应始终返回零值或导致返回的结构用零填充。 (遗憾的是我找不到规范,但this blog post包含摘要。)