我有以下格式的超类和子类:
ParentClass.h
@interface ParentClass : NSObject
-(ParentClass *)field:(NSArray *)fields;
@end
ParentClass.m
#import "ParentClass.h"
@implementation ParentClass
-(id)init{
self = [super init];
if (self == nil) {
return self;
}
return self;
}
-(ParentClass *)field:(NSArray *)fields{
ParentClass *pc = [[ParentClass alloc] init];
// code
return pc;
}
@end
Subclass.h
@interface Subclass : ParentClass
-(Subclass *)field:(NSArray *)fields;
@end
Subclass.m
#import "Subclass.h"
@implementation Subclass
-(id)init{
self = [super init];
if (self == nil) {
return self;
}
return self;
}
-(Subclass *)field:(NSArray *)fields{
// code
return (Subclass *)[self field:fields];
}
@end
我猜问题就在这里。
return(Subclass *)[self field:fields];
我没有按照我应该的方式访问父类方法。任何人都能说出应该是正确的方法吗?
如果我这样打电话怎么办?
- (Subclass *)subClassField:(NSArray *)fields {
return (Subclass *)[self field:fields];
}
我取代了 - (子类*)字段:(NSArray *)字段;
与 - (Subclass *)subClassField:(NSArray *)fields;
答案 0 :(得分:2)
首先请注意此代码
-(ParentClass *)field:(NSArray *)fields{
ParentClass *pc = [[ParentClass alloc] init];
// code
return pc;
}
从软件设计的角度来看,看起来并不正确。根据您发布的内容,ParentClass
实例似乎可以从字段方法创建并返回其自己类型的其他实例。这看起来不太好,但根据你的意图可能会很好。
如果有意义,请考虑制作ParentClass
和FieldClass
个不同的类。
关于子类,做你想做的事的方式是:
-(ParentClass *)field:(NSArray *)fields
{
// code
return [super field:fields];
}
请注意,我将返回的类型更改为(ParentClass *)
,将self
更改为super
。您不能在ParentClass
对象的位置返回SubClass
对象(后者可能具有以前不知道的额外数据)。相反的做法是有效的(当有人希望收到Subclass
类型的对象时,您可以返回ParentClass
个对象。
答案 1 :(得分:1)
话虽如此,目前还不清楚你想要达到的目标,但我会说出错了。首先是不足以将指针强制转换为基类指针,调用超类方法,你应该这样调用它:
return (Subclass*) [super field:fields]; // Still wrong
但是你打破了多态,并且正如方法签名所说,你正在返回一个Subclass
对象,而调用这个方法的用户希望有一个Subclass
对象,但在首先调用一个刚刚由子类实现的方法,它崩溃了,因为你正在返回一个超类的实例。也许足以让你更改方法签名以返回ParentClass
指针,但这会使方法无效,为什么要覆盖它?你正在尝试做什么并不清楚,你的逻辑路径是什么。
修改
看过你在Github上发布的代码,情况就差异很大了。在Java代码中,方法field
返回this
,因此不会创建新对象,并且该方法仅用于副作用。 add
方法不会破坏多态性,因为只有对象引用属于父类类型,但如果在子类上执行它返回对象本身(this
),它是子类类型。
在Objective-C中,对于这些情况,使用id
类型,它用于表示任何类的任何对象指针。你也可以使用ParentClass
类型,但我会坚持惯例。这是一个指示性代码:
@implementation ParentClass
@synthesize endpoint
- (id) add: (NSString*) endpoint fields: (NSArray*) fields
{
<code>
return self;
}
- (id) field: (NSArray*) fields
{
return [self add: self.endpoint fields: fields];
}
@end
@implementation SubClass
- (id) field: (NSArray*) fields
{
< Additional code >
return [self add: self.endpoint fields: fields];
}
@end