繁体   English   中英

目标C子类化:这合适吗?

[英]Objective C Subclassing: Is this proper?

因此,我正在使用cocos2d框架开发iPad游戏。

我的游戏要求在“关卡”开始时生成不同的建筑物。 用户可以选择他们要使用的建筑物。

这里的一项重要功能是,不同的建筑物在被按下时将执行不同的动作。

我有一个看起来像这样的父类:

BaseBuilding.h

@interface BaseBuilding : NSObject {
    CGRect _hitBox;
    NSString *_name;

    CCSprite *_sprite;
    int _identifier;
    int _health;

    int _coolDownDuration;
}

@property (atomic, retain) CCSprite *sprite;
@property (atomic, assign) int identifier;
@property (atomic, assign) int health;

- (void) onBuildingPressed;
- (id) initWithName:(NSString*)baseName;
- (id) initBuilding;
- (CGRect) hitBox;
- (void) sustainDamage;

所以我的大多数建筑物都很相似。 每个建筑物都有自己的initBuilding方法,该方法将覆盖父级。 initBuilding方法将调用super initWithName方法,该方法随后会在plist中查找有关该建筑物的信息(精灵名称等)。

每个建筑物还具有自己的onBuildingPressed方法,该方法还将覆盖父方法。 这是非常重要的功能。

我遇到的问题:

我想根据玩家的选择生成建筑物。 我目前正在做的事情是这样的:

BaseBuilding *building;

switch (choice) {
    case 1:
        building = [BuildingX alloc];
        [building initBuilding];
        break;
    case 2:
        building = [BuildingY alloc];
        [building initBuilding];
        break;
    case 3:
        building = [BuildingZ alloc];
        [building initBuilding];
        break;
}

return building;

由于BuildingX,BuildingY和BuildingZ都是BaseBuilding的子类,因此initBuilding确实会调用正确的方法。

稍后我可以打电话给[rightBuilding onBuildingPressed]; 并且它按预期工作。

BuildingX具有其他建筑物所没有的removeAmmo方法,因此我必须调用它: [(BuildingX*)centerBuilding removeAmmo]

这是正确的方法还是更好的方法?

我唯一注意到的是,如果您有许多子类(假设所有子类都按字母顺序排列),则可以根据选择的值获取类对象,从而更快,更优雅地完成此工作:

NSString* className= [NSString stringWithFormat: @"Building%c",'X'-1+choice];
Class class= NSClassFromString(className);
BaseBuilding* building= [[class alloc] initBuilding];

但这只是样式和速度的问题(我是说编写代码)。 您的方法非常好,没有任何问题。

您可以在运行时验证类,以确保这里没有错误的余地,如下所示:

if ( [centerBuilding respondsToSelector:NSSelectorFromString(@"removeAmmo")] ) {
    [centerBuilding performSelector:NSSelectorFromString(@"removeAmmo"];
}

对我来说似乎合乎逻辑。 我不知道它是否时尚,势利的人可以为您确定。 如果可行,则可行。 我认为修复未损坏的内容没有意义。

是的,这是正确的。 但:

1)如果将所有子类都转换为父类,并且需要使用子类的特定方法,那么仅在某些情况下,将其转换为正确的子类是无用的。 尝试将removeAmmo设为基本方法...

要么

2)使建筑物子类从内部调用removeAmmo方法,并在类别中声明removeAmmo方法

从外部角度来看,BaseClass没有removeAmmo方法,因此声明一个公共方法(调用该方法只能将您的对象重新投射到特定的子类)不是逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM