0

这很可能是一个愚蠢的问题,但无论如何。在目标 c 中,在子类的启动方法中,通常设置 self=[super init]。现在, self 属于子类,不需要转换,这意味着(或不......)父类的 init 方法以某种方式返回一个实际上属于子类的对象。

所以我的问题是:我可以在父类中定义其他方法或属性,当从子类调用时返回子类的对象?我认为Java中有类似的东西称为工厂方法,所以也许这个问题并不太离谱..

编辑 1.让我更好地解释我的意思:我知道我可以在 ParentClass 方法中找到,我实际上是在对 ChildClass 类的对象进行操作。这是通过查看[self class]。但是,我想在 ParentClass 中声明一个从子类返回对象的方法,而无需事先知道子类将是哪个类。更好的是,我希望返回的对象甚至不需要正式的转换。

例如,我想要父类中的一个方法,它执行以下操作:

-(ChildClass *) partialCopyOfSelf {
//returns an object which is a partial copy of self (only copying properties that also
// exist in parent class, but such that applying [result class] will yield the child class
// and will require no further conversion

(ChildClass *) copy=[[ChildClass alloc] init];
//now copy stuff
return copy;
} 

现在在子类中,我希望能够实现以下类型的东西:

-(MyClass *) copyOfSelf {
MyClass *copy=[super partialCopyOfSelf];
// now copy properties that only exist in my child class
return copy;
}

编辑 2(来自我写给@wbyoung 的评论)。我想要这个的原因是,在某些时候我可能想将父类的属性从 ivars 更改为可能只是计算一些值,例如,所以孩子不知道如何正确复制它们。我写这篇文章是因为有人可能对如何完成相同的任务有更好的想法。

4

3 回答 3

2

init方法实际上只是使用已经创建的子类的对象。这是对它的调用alloc。那是使用您向其发送消息的类来确定如何分配对象。

话虽如此,您可以覆盖子类中的方法。消息总是发送到对象和方法查找从最顶层的类开始。

你也可以做一些事情,比如[self class]在父类中找出你的类型。不过,这只会让你到目前为止。[[self class] displayColor]将允许您执行诸如在基类中实现方法和默认类方法实现之类的操作,但根据需要覆盖子类中的类方法。

于 2012-04-15T14:24:24.577 回答
0

这很可能是一个愚蠢的问题,但无论如何。在目标 c 中,在子类的启动方法中,通常设置 self=[super init]。现在, self 属于子类,不需要转换,这意味着(或不......)父类的 init 方法以某种方式返回一个实际上属于子类的对象。

嗯,不完全是。-init默认返回id几乎任何对象。它告诉编译器它是一个对象并让它假设你知道你在做什么,所以你不需要强制转换它。


所以我的问题是:我可以在父类中定义其他方法或属性,当从子类调用时返回子类的对象?我认为Java中有类似的东西称为工厂方法,所以也许这个问题并不太离谱..

当您self在超类的实现中返回时,您将返回与调用该方法的对象相同的对象。所以答案是肯定的。

于 2012-04-15T14:28:25.033 回答
0

是的 。Obj-C 遵守大多数 OO 语言中的所有子类化规则。

例如..

@interface Foo : NSObject

@property (readonly) BOOL thing1;
@property (readonly) CGFloat width;

@end

@implementation Foo

-(BOOL)thing1
{
 return YES;
}

-(CGFloat)width
{
 return 30.0f;
}

@end

的接口Bar不需要 or 的声明或thing1实现width

@interface Bar : Foo

@end

@implementation Bar

-(BOOL)thing1
{
if(test) return YES; 
else return NO;
}

-(CGFloat)width
{
 return [super width] + 20.0f;
}

@end

但是,您可以实现thing1和/或width在子类中提供不同的值。

父类的实例总是返回YES属性thing1,而其子类 Bar 可以根据测试结果返回 YES 或 NO(例如)。

另一个属性width使用父类值并更改它。

于 2012-04-15T14:22:34.307 回答