Objective-C类方法的子类化

5

我有一个关于子类化和类方法的问题。

我有一个基类 MyBaseClass ,它有一个方便的类方法

+ (id)giveMeAClassUsing:(NSString *)someParameter;

MyBaseClass 不是单例。

现在,我希望创建一个 MyBaseClass 的子类,让我们称之为 MyChildClass 。 我希望在 MyChildClass 上也有相同的类方法。 此外,当我这样做时,我还希望初始化 MyChildClass 上的实例变量。

是否像这样做:

+ (id)giveMeAClassUsing:(NSString *)someParameter {

      MyChildClass *anInstance = [super giveMeAClassUsing:someParameter];
      anInstance.instanceVariable = [[UIImageView alloc] initWithFrame:someFrame];

      return anInstance;
}

是否有效?

非常感谢您的帮助(提前)以及解决我的困惑并澄清一些概念!

干杯!


是的,这就是真正的类方法静态方法之间的关键区别... - bbum
2个回答

8

这将很好地发挥作用。

更好的方式可能是以这样一种方式定义您的便利构造函数,以便您不需要覆盖它:

 + (id)myClassWithString: (NSString *)string {
     return [[[self alloc] initWithString:string] autorelease];
 }

无论你的超类或它的任何子类被调用时,这都会做正确的事情。
然后,只需要改变你的子类中的initWithString:方法来处理初始化即可。
- (id)initWithString: (NSString *)string {
    return [self initWithString:string andImageView:[[[UIImageView alloc] initWithFrame:someFrame] autorelease]] ;
}

请问您能否再详细解释一下呢?我的当前基类实现是:+ (id)giveMeAClassUsing:(NSString *)someParameter { BaseClass *anInstance = [[self alloc] initUsingCustomInstanceMethod:aParameter]; return anInstance;} 那么,我在子类中只需要重写 initUsingCustomInstanceMethod:aParameter 方法吗? - codeBearer
没错,这就是我想说的。你现在的写法也可以正常工作,但如果我在阅读你的代码时,我可能只会期望 init... 方法被重写。 - jscs
太棒了!你说得对!!!我完全忘记了我将引用[ChildClass giveMeAClassUsing:aParameter],因此基类的代码调用[self alloc]实际上将引用ChildClass。然后,我调用[super initUsingCustomInstanceMethod:aParameter]并进行自定义初始化。:D 非常感谢! - codeBearer
只是确认一下,从我所看到的方式来看,我仍然需要从我的子类自定义初始化程序中调用 [super initUsingCustomInstanceMethod:aParameter],对吗? - codeBearer
你需要在子类的指定初始化方法中调用父类的指定初始化方法。对于我的建议,这意味着在子类的initUsingCustomInstanceMethod:andImageView:中执行 [super initUsingCustomInstanceMethod:aParameter] - jscs
没错,没错。 :) 这正是我要问的!再次感谢库斯托先生! :) - codeBearer

5

当然是有效的。

不过需要注意的是,在超类中,应该使用 self 引用类本身,而不是用类名引用超类。

这样是不好的:

// MySuperClass // BAD :(
+ (id)giveMeAClassUsing:(NSString *)someParameter {
  return [[[MySuperClass alloc] initWithParam:someParameter] autorelease];
}

但这很好!

// MySuperClass // GOOD! :D
+ (id)giveMeAClassUsing:(NSString *)someParameter {
  return [[[self alloc] initWithParam:someParameter] autorelease];
}

否则,当你创建一个子类并调用super时,实际上你没有初始化正确的类。使用self可以让被实例化的类可变而不需要重写类方法。

是的,正如上面评论中发布的那样,这就是我初始化超类的方式:+ (id)giveMeAClassUsing:(NSString *)someParameter { BaseClass *anInstance = [[self alloc] initUsingCustomInstanceMethod:aParameter]; return anInstance;} - codeBearer
谢谢您的及时回复和建议。 :) - codeBearer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接