类工厂方法实现

sys*_*bug 2 objective-c

所以我正在研究Objective-C的Apple文档(在进入iphone开发之前).其中一个练习指出我应该创建一个指定的初始化器(有3个参数)和合适的工厂方法.

现在我根据我的理解做了这个,但我无法实现工厂方法,因为我不知道我是否应该在其实现中使用alloc和init?

练习:

声明并实现一个新的指定初始化程序,用于使用指定的名字,姓氏和出生日期创建XYZPerson,以及合适的类工厂方法.不要忘记覆盖init以调用指定的初始化程序.

代码:

//.h 

-(id)initWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob;

//.m
-(id)initWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *)dob{
    self = [super init];
    return [self initWithNameAndDob:fName last:lName birth:dob];
}
Run Code Online (Sandbox Code Playgroud)

实施中缺少什么?

谢谢,

Gab*_*lla 16

声明并实现一个新的指定初始化程序,用于使用指定的名字,姓氏和出生日期创建XYZPerson ...

你在声明中是正确的,但你的实现是递归的,因为它正在调用它自己.做点什么

//.h
-(id)initWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob;
//.m
-(id)initWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *)dob{
    if(self = [super init]) {
        // use the parameters to do something, eg.
        _fName = fName; // assuming you have an ivar called _fName 
        _lName = lName; // assuming you have an ivar called _lName
        _dob = dob; // assuming you have an ivar called _dob
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

然后

......以及合适的班级工厂方法.

工厂方法是生成对象实例的类方法.最常见的实现是让它分配和初始化对象的新实例并将其返回.

//.h
+(instancetype)personWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob {


//.m
+(instancetype)personWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob {
return [[XYZPerson alloc] initWithNameAndDob:fName last:lName birth:dob];
}
Run Code Online (Sandbox Code Playgroud)

最后

不要忘记覆盖init以调用指定的初始化程序.

由于您设计的初始化程序是initWithNameAndDob:last:birth:您的init实现必须调用它.设计的初始化程序的参数必须是合理的默认值,在这种情况下nil是好的.

-(id)init {
     return [self initWithNameAndDob:nil last:nil birth:nil];
 }
Run Code Online (Sandbox Code Playgroud)

作为最后的评论,我想指出初始化程序的命名约定不是那么好.一个更合适和可读的人

-(id)initWithFirstName:(NSString *)fName lastName:(NSString *)lName dateOfBirth:(NSDate *) dob;
Run Code Online (Sandbox Code Playgroud)

  • 编译器将知道类型,它可以帮助您在编译器时捕获错误.对`init`使用`id`是必要的"解决方法",而不是理想的功能. (3认同)

i.A*_*oor 5

Gabriele Petronella的优秀解释,但有问题.

+(instancetype)personWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob {
return [[XYZPerson alloc] initWithNameAndDob:fName last:lName birth:dob];
}

It should be replaced with 
+(instancetype)personWithNameAndDob:(NSString *)fName last:(NSString *)lName birth:(NSDate *) dob {
return [[self alloc] initWithNameAndDob:fName last:lName birth:dob];
}
Run Code Online (Sandbox Code Playgroud)

规则: 不要按名称引用自己的类,因为你不知道具体的类是什么.您将无意中切断通过子类化扩展和覆盖类的能力.相反,要在类的工厂方法中分配实例:[self alloc] 参考: http ://qualitycoding.org/factory-method/