在iOS中将对象转换为其子类

时间:2014-03-04 22:06:25

标签: ios objective-c oop

我有一个Person对象,其中包含nameemailbirthdate等内容。

我还有一个名为Person的{​​{1}}子类,其中包含MemberyearJoined等内容。

在我的代码中,如何获取现有title并将其转换为Person?例如:

Member

我收到编译器错误,因为类不匹配。但是子类应该继承其父类的所有属性,所以我正在寻找一种方法来说“这个Member *mem = self.person; 对象现在应该是Person对象。”

这有意义吗?

2 个答案:

答案 0 :(得分:3)

这样做的一种方法是在initWithPerson类中声明memberFromPerson类方法和Member静态方法:

@interface Member : Person
{
    NSString *title;
...
}

- (id)initWithPerson:(Person *)aPerson title:(NSString *)aTitle;

+ (Member *)memberFromPerson:(Person *)aPerson title:(NSString *)aTitle;

@end

在您的实施中:

@implementation Member

- (id)initWithPerson:(Person *)aPerson title:(NSString *)aTitle
{
    if (self = [super initWithName:aPerson.name email:aPerson.email birthdate:aPerson.birthdate])
    {
        self.title = aTitle;
    }
    return self;
}

+ (Member *)memberFromPerson:(Person *)aPerson title:(NSString *)aTitle
{
    return [[Member alloc] initWithPerson:aPerson title:aTitle];
}

@end

然后,当您想将Person个实例转换为Member时,您只需要致电:

Member *newMember = [Member memberFromPerson:myPerson title:@"New member!"];

当然,你可以自定义所有这些,具体取决于如何加入其他变量(如title或year)(如果正确初始化所有内容,你可以创建memberFromPerson:的版本,而不需要任何其他参数)。

答案 1 :(得分:2)

面向对象的3个最重要的属性中有2个是多态和继承。

鉴于A类,继承允许您创建一个继承自A的B类,这意味着B继承了A中实现的所有数据成员和方法,并且它使您能够:

  • 覆盖A中定义的方法,专门化其行为
  • 添加新方法和数据成员

多态性允许在需要超类A的任何地方使用继承的类B.

当您从A继承B时,B“知道”A是什么。相反的不是真理,因为A不知道从中继承了多少和哪些类。所以它不能表现得像是一个继承者的实例。

在您的情况下,Member继承自Person,因此Member可用于需要Person个实例的任何地方。但反过来是不可能的,除非你知道你的代码中发生了这种情况:

Member *member = [[Member alloc] init];
Person *person = member; // This is ok, person is a superclass of member
...
...
Member *member2 = (Member *) person; // This, although stylistically questionable, is possible because you know person is an instance of Member

因此,当您100%确定它是Person的实例时,您可以从Member投射到Member,即使保留在Person类型的变量中也是如此。< / p>

在以下情况中改为:

Person *person = [[Person alloc] init];
Member *member = (Member *) person;

编译器不会抱怨,但很可能会收到运行时异常。

为了明确这个概念,让我做一个简单的比较。 MobilePhone是基类,SmartPhone从中继承。 MobilePhone有一些功能(您可以拨打和接听电话,发送和接收短信等)。 SmartPhone的行为类似于MobilePhone,因此您可以像使用MobilePhone一样使用它,但您也可以执行更多操作,例如从AppStore安装应用程序(顺便提一下) MobilePhone'是iPhone ;-)),发送推文,阅读电子邮件,查看日历,天气等。所有这些无法通过MobilePhone 完成。

对于解决方法,@ Romain提出的(好)解决方案是一种广泛使用的常见模式。但是你必须考虑到它不是演员Member的新实例是使用从Person复制的数据创建的。在某些情况下,了解这一点非常重要。