Вызов назначенного инициализатора суперклассов вызывает подклассы

У меня есть то, что кажется достаточно простой проблемой, но я просто понятия не имею, почему она работает так, как есть.

У меня есть класс Shape, который имеет подкласс Square.

Когда я вызываю Square и вызываю его назначенный инициализатор, в self = [super init] он вызывает суперкласс. Однако, когда суперкласс вызывает свой назначенный инициализатор, названный так же, как один из подклассов, он вызывает подкласс.

В итоге я получаю бесконечный цикл подкласса, вызывающего init в суперклассе, и тот, который вызывает инициализатор подклассов.

Как я могу решить эту проблему? Должен ли я убедиться, что имена моих инициализаторов достаточно разные, чтобы этого не могло произойти?

Shape.h

#import <Foundation/Foundation.h>

@interface Shape : NSObject

@property (nonatomic) CGPoint position;
@property (nonatomic) float width;
@property (nonatomic) float height;
@property (nonatomic, readonly) float area;

- (id)initWithWidth:(float)width andHeight:(float)height andPosition:(CGPoint)position;
- (id)initWithWidth:(float)width andHeight:(float)height;
- (id)initWithWidth:(float)width;
- (id)init;

- (NSString *)drawShape;

@end

-

Shape.m

#import "Shape.h"

@implementation Shape

- (id)initWithWidth:(float)width andHeight:(float)height andPosition:(CGPoint)position
{
    self = [super init];

    if (self) {
        self.width = width;
        self.height = height;
        self.position = position;
    }

    return self;
}

- (id)initWithWidth:(float)width andHeight:(float)height
{
    return [self initWithWidth:width andHeight:height andPosition:CGPointMake(100, 100)];
}

- (id)initWithWidth:(float)width
{
    return [self initWithWidth:width andHeight:1.0f andPosition:CGPointMake(100, 100)];
}

- (id)init
{
    CGPoint defaultPoint = CGPointMake(100, 100);

    return [self initWithWidth:1.0 andHeight:1.0 andPosition:defaultPoint];
}

- (NSString *)drawShape
{
    NSString *outputShape = [NSString stringWithFormat:@"Drawing shape - (%.2f,%.2f), width - %f, height - %f", self.position.x, self.position.y, self.width, self.height];

    NSLog(@"%@", outputShape);

    return outputShape;
}

@end

-

Square.h

#import <Foundation/Foundation.h>
#import "Shape.h"

@interface Square : Shape

- (id)initWithWidth:(float)width andPosition:(CGPoint)position;
- (id)initWithWidth:(float)width andHeight:(float)height andPosition:(CGPoint)position;
- (id)initWithWidth:(float)width andHeight:(float)height;
- (id)initWithWidth:(float)width;

@end

-

Square.m

#import "Square.h"

@implementation Square

- (id) initWithWidth:(float)width andPosition:(CGPoint)position
{
    self = [super init];

    if (self) {
        self.width = width;
        self.height = width;
        self.position = position;
    }

    return self;
}

// Returning the width as the width and height as you can't make a square with different sides
- (id)initWithWidth:(float)width andHeight:(float)height andPosition:(CGPoint)position
{
    return [self initWithWidth:width andPosition:position];
}

- (id)initWithWidth:(float)width andHeight:(float)height
{
    return [self initWithWidth:width andPosition:CGPointMake(100, 100)];
}

- (id)initWithWidth:(float)width
{
    return [self initWithWidth:width andPosition:CGPointMake(100, 100)];
}

- (NSString *)drawShape
{
    NSString *outputShape = [NSString stringWithFormat:@"Drawing shape - (%.2f,%.2f), width - %.2f, height - %.2f", self.position.x, self.position.y, self.width, self.height];

    NSLog(@"%@", outputShape);

    return outputShape;
}

@end

person Mark Reid    schedule 19.09.2013    source источник
comment
Почему в initWithWidth:(float)width andPosition:(CGPoint)position вы звоните [super init] вместо [super initWithWidth:width andHeight:width andPosition:position]?   -  person Mark S.    schedule 19.09.2013
comment
Хорошая точка зрения. Мне не приходило в голову, что это то, что я должен делать, а не просто вызывать init.   -  person Mark Reid    schedule 19.09.2013


Ответы (1)


Здесь нужно переопределить -[Square initWithWidth:andPosition:], например:

- (id)initWithWidth:(float)width andPosition:(CGPoint)position
{
    self = [super initWithWidth:width andHeight:width andPosition:position];
    return self;
}
person Aaron Golden    schedule 19.09.2013
comment
Спасибо. В этом есть смысл. - person Mark Reid; 19.09.2013