我目前正在学习复合对象的使用,我有几个问题。
为什么以及何时应该使用复合对象?我们是否只在我们想要使用其实例但使用完全不同的方法的类时使用它?
考虑到我想从Rectangle类创建一个Square类(我将其命名为Shape),但不打算在Shape类中使用initWithHeight:andWidth:。这意味着我将以这种方式声明Square标题。
使用头文件
@interface Square : NSObject {
Shape *square;
}
- (Square*) initWithSide: (int) s;
- (void) setSide: (int) s;
- (int) side;
- (int) area;
- (int) perimeter;
- (id) free;
@end
实施
@implementation Square
- (Square*) initWithSide: (int) s
{
if(self = [super init])
{
square = [[Shape alloc] initWithHeight:s andWidth:s];
}
return self;
}
- (void) setSide: (int) s
{
[square setHeight:s];
[square setWidth:s];
}
- (int) side
{
return [square width];
}
- (int) area
{
return [square width]*[square height];
}
- (int) perimeter
{
return 2*([square width]+[square height]);
}
- (id) free
{
[square release];
return square;
}
@end
问题:我做得对吗?有没有更好或更整洁的方法来构造复合对象,因为我发现我写的代码有点奇怪。特别是释放内存分配的方法。由于我在主文件中有[mySquare release],这意味着我需要在[mySquare发布]之前首先[mySquare免费]。我可以将它们组合起来,所以我只需要调用[mySquare release]来释放内存分配吗?
答案 0 :(得分:0)
除了奇怪和错误的free
方法和缺少的dealloc
(假设你没有使用垃圾收集),看起来绝对正常。
我可能不会将实例变量命名为square
。
此外,您可以考虑在-init
中进行测试,以确保成功分配square
:
- (id) initWithSide: (int) s
{
self = [super init];
if(self != nil)
{
square = [[Shape alloc] initWithHeight:s andWidth:s];
if (square == nil)
{
[self release];
return nil;
}
}
return self;
}
初始化程序的返回类型应始终为id
编辑:对于dealloc方法
-(void) dealloc
{
[square release];
[super dealloc];
}
答案 1 :(得分:0)
我偶然发现了你的帖子。虽然,我不回答你的问题:我刚刚创建了一个example project dealing with the composite pattern。也许有帮助。
在示例中,我尝试使用相同的方法构建接口FooProtocol
以访问具体类型FooObject
和FooCollection
。这样,对象具有的透明类型。 - 您可以在EnumerableCompositeAppDelegate
中找到示例。只需编译并运行该项目。