我有一个Person
对象,其中包含name
,email
,birthdate
等内容。
我还有一个名为Person
的{{1}}子类,其中包含Member
,yearJoined
等内容。
在我的代码中,如何获取现有title
并将其转换为Person
?例如:
Member
我收到编译器错误,因为类不匹配。但是子类应该继承其父类的所有属性,所以我正在寻找一种方法来说“这个Member *mem = self.person;
对象现在应该是Person
对象。”
这有意义吗?
答案 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的任何地方使用继承的类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
复制的数据创建的。在某些情况下,了解这一点非常重要。