I am trying to re-write some code of old project, and ideally I want to achieve below code style, but I got a lot of compile error saying dataModel don't have getLineColor method.
The abstract question is, can I change an inherited object A's class in sub view controller to a sub class A2, while the object A in parent view controller is class A1 that is the super class of A2, and how can I do it correctly? Thank in advance.
Update: I compile it, but I have met another run time error, I tried to overwrite the setter of dataModel in sub view controller. How to correctly write the setDataModel in sub class?
@implementation SubViewController
#pragma mark - setter of dataModel
- (void)setDataModel:(ChartModel *)dataModel { // it stucks at this func name
@end
error trace is
[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)
EDIT:
@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
One thing you could do is declare a LineChartModel
variable and not property and @synthesize
dataModel to that ivar:
@interface LineChartViewController: ChartViewController {
LineChartModel *_lineChartModel;
}
-(void)drawLine;
@end
@implementation LineChartViewController
synthesize dataModel = _lineChartModel;
....
So from the outside it looks like you have a ChartModel
, but inside the class you have LineChartModel
. You will have to apply changes to _lineCharModel
directly inside your class.
HOWEVER this is NOT my definition of better OOP!!! There's clearly a fault with the design if you need to cast your variables in subclass.
Another option I discovered after pasting this code into the editor is just use self.variable
(which by the way, you should've already been doing).
@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
Probably you want to say:
Can I change the class C of a property already declared in a base class in a subclass to a subclass of C?
This is the set-up
@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
I have no problem to access the property subclass' method in the holder's subclass:
@implementation HolderSubclass
- (void)useIt
{
[self.property method]; // No error or warning
}
@end
In addition to my comment below, I suspect that something like this happens:
// 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
This error is correct. If this is the error, it is solvable. But first we have to clarify that.
BTW: This has nothing to do with better OOP. First of all this is a problem of class based programming languages, not of object orientated programming languages. Second I cannot see that this set-up will break a rule of class based or object orientated programming, esp. it fulfills Liskov's rule.
User contributions licensed under CC BY-SA 3.0