如何在Objective-C中更改子类中的属性类

时间:2015-04-10 11:16:55

标签: objective-c

我正在尝试重新编写一些旧项目的代码,理想情况下我想实现下面的代码样式,但是我得到了很多编译错误,说dataModel没有getLineColor方法。

抽象的问题是,我可以将子视图控制器中的继承对象A的类更改为子类A2,而父视图控制器中的对象A是A2的超类A1,我该怎么办?它正确吗?提前谢谢。

更新:我编译它,但我遇到了另一个运行时错误,我试图覆盖子视图控制器中的dataModel的setter。如何在子类中正确编写setDataModel?

@implementation SubViewController
#pragma mark - setter of dataModel
- (void)setDataModel:(ChartModel *)dataModel { // it stucks at this func name
@end

错误跟踪

[SubChartViewController setDataModel:](self=0x00000000, _cmd=0x00000000, dataModel=0x00000031) + 12 at BDPAxisChartViewController.m:295, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0xbf774ffc)

编辑:

@interface ChartModel : NSObject
-(BOOL)chartModelhasData;
@end

@interface LineChartModel : chartModel
-(void)getLineColor;
@property (nonatomic, strong) NSArray* seriesNameArray;
@end

@interface ChartViewController: UIViewController
@property (nonatomic, strong) ChartModel *dataModel;
-(void)layoutChartCanvas;
@end

@implementation ChartViewController
-(void)layoutChartCanvas {
    if ([self.dataModel chartModelhasData]) {
        self.view.hidden = NO;
    }
}
@end

@interface LineChartViewController : ChartViewController
// pay attension here, same name but a sub class of chartModel
@property (nonatomic, strong) LineChartModel *dataModel; 
-(void)drawLine;
@end

@implementation LineChartViewController
-(void)drawLine {
    UIColor *color = [self.dataModel getLineColor];
    [self drawLine];
    NSArray *tempArray = [self.dataModel.seriesNameArray copy];
}
@end

2 个答案:

答案 0 :(得分:1)

您可以做的一件事是将LineChartModel变量而不是属性和@synthesize dataModel声明为该ivar:

@interface LineChartViewController: ChartViewController {
     LineChartModel *_lineChartModel;
}
-(void)drawLine;
@end

@implementation LineChartViewController
synthesize dataModel = _lineChartModel;
....

所以从外面看起来你有一个ChartModel,但在课堂上你有LineChartModel。您必须直接在班级内对_lineCharModel进行更改。

但这不是我对更好的OOP的定义!!! 如果您需要在子类中转换变量,那么设计显然是错误的。


我将此代码粘贴到编辑器后发现的另一个选项就是使用self.variable(顺便说一下,你应该已经在做了)。

@interface ChartModel : NSObject
- (BOOL)chartModelhasData;
@end

@interface LineChartModel : ChartModel
- (UIColor *)getLineColor;
@end

@interface ChartViewController: UIViewController
@property (nonatomic, strong) ChartModel *dataModel;
- (void)layoutChartCanvas;
@end

@implementation ChartViewController
- (void)layoutChartCanvas {
    if ([self.dataModel chartModelhasData]) {
        self.view.hidden = NO;
    }
}
@end

@interface LineChartViewController : ChartViewController
// pay attension here, same name but a sub class of chartModel
@property (nonatomic, strong) LineChartModel *dataModel;
- (void)drawLine;
@end

@implementation LineChartViewController
- (void)drawLine {
    UIColor *color = [self.dataModel getLineColor];
    [self drawLine];
}
@end

答案 1 :(得分:1)

可能你想说:

  

我可以将已经在子类中的基类中声明的属性的类C更改为C的子类吗?

这是设置

@interface PropertyClass : NSObject
@end

@interface PropertySubclass : PropertyClass
- (void)method;                              // Additional method
@end

@interface HolderClass : NSObject
@property PropertyClass *property;           // Property is of base class
@end

@implementation HolderClass
@end

@interface HolderSubclass : HolderClass
@property PropertySubclass *property;        // Property is of subclass
@end

访问holder的子类中的属性子类'方法没有问题:

@implementation HolderSubclass
- (void)useIt
{
  [self.property method]; // No error or warning
}
@end

除了下面的评论,我怀疑会发生类似的事情:

// Create a subclass' object
HolderSubclass *object1 = [HolderSubclass new]; 
…

// Refer this object from a reference that is typed to HolderClass
// **This applies to all usages of self inside @implementation HolderClass**
HolderClass *object2 = object1; // Of course more complex

id value = [object2 method]; // Error

此错误是正确的。如果这是错误,则可以解决。但首先我们必须澄清这一点。


BTW:这与更好的OOP无关。首先,这是基于类的编程语言的问题,而不是面向对象的编程语言。其次,我看不出这种设置会破坏基于类或面向对象的编程规则,尤其是。它符合Liskov的规则。

http://en.wikipedia.org/wiki/Liskov_substitution_principle