我有一个基本的Point
包装类:
@interface Point : NSObject
@property (nonatomic) CGPoint point;
- (instancetype)initWithPoint:(CGPoint)point;
@end
由Line
s:
Point
类
@interface Line : NSObject
@property (nonatomic, strong) Point startPoint;
@property (nonatomic, strong) Point endPoint;
+ (NSArray *)linesConnectingPoints:(NSArray *)points;
- (instancetype)initWithStartPoint:(Point)startPoint endPoint:(Point)endPoint;
@end
linesConnectingPoints:
是一种方便的方法,用于创建将点数组连接在一起的行数组(因此,如果您有4个Point
的数组,则调用linesConnectingPoints:
可能会创建一个4 Line
s的数组,表示四边形的边。)
@implementation Line
+ (NSArray *)linesConnectingPoints:(NSArray *)points
{
NSMutableArray *lines = [[NSMutableArray alloc] initWithCapacity:points.count];
int i;
for (i = 0; i < points.count - 1; i++)
{
lines[i] = [[self alloc] initWithStartPoint:points[i] endPoint:points[i+1];
}
// The final line connects the last point and the first point
lines[i] = [[self alloc] initWithStartPoint:points[i] endPoint:points[0]];
return lines;
}
...
@end
现在我想创建一个名为Line
的{{1}}子类,它添加了一个额外的线条粗细属性:
ThickLine
@interface ThickLine : Line
@property (nonatomic) float thickness;
- (instancetype)initWithStartPoint:(Point)startPoint
endPoint:(Point)endPoint
thickness:(float)thickness;
@end
成为指定的初始化程序,如下所示:
initWithStartPoint:endPoint:thickness
现在我可以致电// Overriding the superclass' designated initializer
- (instancetype)initWithStartPoint:(Point)startPoint endPoint:(Point)endPoint
{
return [self initWithStartPoint:startPoint endPoint:endPoint thickness:1];
}
- (instancetype)initWithStartPoint:(Point)startPoint
endPoint:(Point)endPoint
thickness:(float)thickness
{
self = [super initWithStartPoint:startPoint endPoint:endPoint];
if (self)
{
_thickness = thickness;
}
return self;
}
,我会得到NSArray *thickLines = [ThickLine linesConnectingPoints:somePoints];
个数组,每个ThickLine
等于1。
但是,如果我想指定厚度怎么办?我可以编写一个方法thickness
并将其粘贴在linesConnectingPoints:withThickness:
中,如此:
ThickLine.m
但这看起来与我已编写的超类'+ (NSArray *)linesConnectingPoints:(NSArray *)points
withThickness:(float)thickness
{
NSMutableArray *lines = [[NSMutableArray alloc] initWithCapacity:points.count];
int i;
for (i = 0; i < points.count - 1; i++)
{
lines[i] = [[self alloc] initWithStartPoint:points[i]
endPoint:points[i+1]
thickness:thickness;
}
lines[i] = [[self alloc] initWithStartPoint:points[i]
endPoint:points[0]
thickness:thickness];
return lines;
}
方法完全相同,只是使用了不同的初始值设定项。
当然,这里的重复是微不足道的,并不是什么大问题,但如果我想创建lineConnectingPoints:
的多个其他子类呢?我可能有Line
,ColoredLine
,LabeledLine
等等,而且我必须为每个子类重写这个“便捷方法”(FancyLine
for { {1}},linesConnectingPoints:withColor:
为ColoredLine
,linesConnectingPoints:withText:
为LabeledLine
,等等。每个便捷方法都与超类的原始方法完全相同,但初始化器中使用的参数除外。
有没有办法减少这里的重复?有些方法可以将重复的代码封装在一个单独的函数中,并且能够指定使用的初始化程序吗?
答案 0 :(得分:0)
这样怎么样?
行:
typedef Line *(^LineFactoryBlock_t)(Point *startPoint, Point *endPoint);
@implementation Line
+(NSArray *)linesConnectingPoints:(NSArray *)points {
return [self linesConnectingPoints:points withFactoryBlock:^Line *(Point *startPoint, Point *endPoint) {
return [[self alloc] initWithStartPoint:startPoint endPoint:endPoint];
}];
}
+(NSArray *)linesConnectingPoints:(NSArray *)points withFactoryBlock:(LineFactoryBlock_t)factory {
NSMutableArray *lines = [[NSMutableArray alloc] initWithCapacity:points.count];
int i;
for (i = 0; i < points.count - 1; i++) {
lines[i] = factory(points[i], points[i+1]);
}
// The final line connects the last point and the first point
lines[i] = factory(points[i], points[0]);
return lines;
}
//...
@end
ThickLine:
+(NSArray *)linesConnectingPoints:(NSArray *)points withThickness:(float)thickness {
return [self linesConnectingPoints:points withFactoryBlock:^Line *(Point *startPoint, Point *endPoint) {
return [[self alloc] initWithStartPoint:startPoint endPoint:endPoint thickness:thickness];
}];
};