Objective-C对象初始化 、 实例方法和参数 、 类方法 、 工厂方法 、 单例模式

2 重构Point2类

2.1 问题

本案例使用工厂方法重构Point2类,类中有横坐标x、纵坐标y两个属性,并且有一个能显示位置show方法。在主程序中创建两个Point2类的对象,设置其横纵坐标,并将它们显示出来。

2.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义类Point2

由于是对Point2类的重构,所以在Day02工程中新添加Point3.h文件用于定义新的类Point2。

代码如下所示:

  1. @interface Point2 : NSObject
  2. {
  3. }
  4. @end

步骤二:在Point2类中添加属性、初始化方法和show方法

首先,在类Point2的声明中添加两个属性,同时再添加无参初始化方法和有参初始化方法的声明和添加show方法的声明。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. -(void)show;
  9. @end

然后,在类Point2的实现部分,即在Point3.m文件中,添加无参初始化方法、有参初始化方法和show方法的实现。

  1. #import "Point3.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. -(void)show
  22. {
  23. NSLog(@"x=%d,y=%d", _x, _y);
  24. }
  25. @end

步骤三:在Point2类中添加工厂方法的声明

工厂方法本质上是类的静态方法,其调用是通过类名直接调用的,与实例方法不同,实例方法是通过对象来调用的。

首先,在类Point2的声明中添加无参工厂方法和有参工厂方法的声明。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. +(id)created;
  9. +(id)createdWithX:(int)x andY:(int)y;
  10. -(void)show;
  11. @end

上述代码中,以下代码:

  1. +(id)created;
  2. +(id)createdWithX:(int)x andY:(int)y;

用于对工厂方法的声明,需要注意的是工厂方法以加号“+”开头,而实例方法则以减号“-”开头。

然后,在类Point2的实现部分,即在Point3.m文件中,添加无参工厂方法和有参工厂方法的实现。方法的函数体实际上就是创建一个对象,然后将其返回。

代码如下所示:

  1. #import "Point3.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. +(id)created
  22. {
  23. Point2 *p = [[Point2 alloc] init];
  24. return p;
  25. }
  26. +(id)createdWithX:(int)x andY:(int)y
  27. {
  28. Point2 *p = [[Point2 alloc] initWithX:x andY:y];
  29. return p;
  30. }
  31. -(void)show
  32. {
  33. NSLog(@"x=%d,y=%d", _x, _y);
  34. }
  35. @end

步骤四:在主程序中使用Point2类

首先在Day02工程中新添加Point3Main.m文件,用于存储主程序,在主程序中创建两个Point2类的对象,一个用无参工厂方法创建,另一个用有参工厂方法创建,最后打印这两个对象。

代码如下所示:

  1. #import "Point3.h"
  2. int main(int argc, const char * argv[])
  3. {
  4. @autoreleasepool {
  5. // insert code here...
  6. Point2 *p = [Point2 created];
  7. [p show];
  8. Point2 *p1 = [Point2 createdWithX:55 andY:77];
  9. [p1 show];
  10. }
  11. return 0;
  12. }

2.3 完整代码

本案例中,类Point2声明,即Point3.h文件,完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. +(id)created;
  9. +(id)createdWithX:(int)x andY:(int)y;
  10. -(void)show;
  11. @end

类Point2实现,即Point3.m文件,完整代码如下所示:

  1. #import "Point3.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. +(id)created
  22. {
  23. Point2 *p = [[Point2 alloc] init];
  24. return p;
  25. }
  26. +(id)createdWithX:(int)x andY:(int)y
  27. {
  28. Point2 *p = [[Point2 alloc] initWithX:x andY:y];
  29. return p;
  30. }
  31. -(void)show
  32. {
  33. NSLog(@"x=%d,y=%d", _x, _y);
  34. }
  35. @end

主程序,即Point3Main.m,完整代码如下所示:

  1. #import "Point3.h"
  2. int main(int argc, const char * argv[])
  3. {
  4. @autoreleasepool {
  5. // insert code here...
  6. Point2 *p = [Point2 created];
  7. [p show];
  8. Point2 *p1 = [Point2 createdWithX:55 andY:77];
  9. [p1 show];
  10. }
  11. return 0;
  12. }

1 重构Point2类

1.1 问题

本案例使用初始化方法重构Point2类,类中有横坐标x、纵坐标y两个属性,并且有一个能显示位置show方法。在主程序中创建两个Point2类的对象,设置其横纵坐标,并将它们显示出来。

1.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义类Point2

由于是对Point2类的重构,所以在Day02工程中新添加Point2.h文件用于定义新的类Point2。

代码如下所示:

  1. @interface Point2 : NSObject
  2. {
  3. }
  4. @end

步骤二:在Point2类中添加属性

在Point2类中添加两个属性,它们为横坐标x,为纵坐标y。

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. @end

步骤三:在Point2类中添加初始化方法

首先,在类Point2的声明中添加无参初始化方法和有参初始化方法的声明。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. @end

上述代码中,以下代码:

  1. -(id)init;

是无参初始化方法,该方法返回一个id类型的变量。id类型是Objective-C中的一种万能指针,相当于C语言中的void*这种数据类型。

上述代码中,以下代码:

  1. -(id)initWithX:(int)x andY:(int)y;

是有参初始化方法,该方法返回一个id类型的变量,同时具有两个形参,一个是整型变量x,另一个是整型变量y。

然后,在类Point2的实现部分,即在Point2.m文件中,添加无参初始化方法和有参初始化方法的实现。

代码如下所示:

  1. #import "Point2.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. @end

上述代码中,以下代码:

  1. if (self = [super init])

是首先发消息[super init]调用基类中的init方法获得self值。

步骤四:在Point2类中添加show方法

show方法用于在控制台上显示Point2类中的两个实例变量的值。

首先,在类Point2的声明中添加show方法的声明。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. -(void)show;
  9. @end

然后,在类Point2的实现部分,即在Point2.m文件中,添加show方法的实现。

代码如下所示:

  1. #import "Point2.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. -(void)show
  22. {
  23. NSLog(@"x=%d,y=%d", _x, _y);
  24. }
  25. @end

步骤五:在主程序中使用Point2类

首先在Day02工程中新添加Point2Main.m文件,用于存储主程序,在主程序中定义两个Point2类的对象,同时使用无参初始化方法和有参初始化方法对两个对象的横坐标和纵坐标赋初值,最后打印这两个对象。

  1. #import "Point2.h"
  2. int main(int argc, const char * argv[])
  3. {
  4. @autoreleasepool {
  5. // insert code here...
  6. Point2 *p = [[Point2 alloc] init];
  7. [p show];
  8. Point2 *p1 = [[Point2 alloc] initWithX:55 andY:77];
  9. [p1 show];
  10. }
  11. return 0;
  12. }

1.3 完整代码

本案例中,类Point2声明,即Point2.h文件,完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. -(void)show;
  9. @end

类Point2实现,即Point2.m文件,完整代码如下所示:

  1. #import "Point2.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. -(void)show
  22. {
  23. NSLog(@"x=%d,y=%d", _x, _y);
  24. }
  25. @end

主程序,即Point2Main.m,完整代码如下所示:

  1. #import "Point2.h"
  2. int main(int argc, const char * argv[])
  3. {
  4. @autoreleasepool {
  5. // insert code here...
  6. Point2 *p = [[Point2 alloc] init];
  7. [p show];
  8. Point2 *p1 = [[Point2 alloc] initWithX:55 andY:77];
  9. [p1 show];
  10. }
  11. return 0;
  12. }

2 重构Point2类

2.1 问题

本案例使用工厂方法重构Point2类,类中有横坐标x、纵坐标y两个属性,并且有一个能显示位置show方法。在主程序中创建两个Point2类的对象,设置其横纵坐标,并将它们显示出来。

2.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义类Point2

由于是对Point2类的重构,所以在Day02工程中新添加Point3.h文件用于定义新的类Point2。

代码如下所示:

  1. @interface Point2 : NSObject
  2. {
  3. }
  4. @end

步骤二:在Point2类中添加属性、初始化方法和show方法

首先,在类Point2的声明中添加两个属性,同时再添加无参初始化方法和有参初始化方法的声明和添加show方法的声明。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. -(void)show;
  9. @end

然后,在类Point2的实现部分,即在Point3.m文件中,添加无参初始化方法、有参初始化方法和show方法的实现。

  1. #import "Point3.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. -(void)show
  22. {
  23. NSLog(@"x=%d,y=%d", _x, _y);
  24. }
  25. @end

步骤三:在Point2类中添加工厂方法的声明

工厂方法本质上是类的静态方法,其调用是通过类名直接调用的,与实例方法不同,实例方法是通过对象来调用的。

首先,在类Point2的声明中添加无参工厂方法和有参工厂方法的声明。

代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. +(id)created;
  9. +(id)createdWithX:(int)x andY:(int)y;
  10. -(void)show;
  11. @end

上述代码中,以下代码:

  1. +(id)created;
  2. +(id)createdWithX:(int)x andY:(int)y;

用于对工厂方法的声明,需要注意的是工厂方法以加号“+”开头,而实例方法则以减号“-”开头。

然后,在类Point2的实现部分,即在Point3.m文件中,添加无参工厂方法和有参工厂方法的实现。方法的函数体实际上就是创建一个对象,然后将其返回。

代码如下所示:

  1. #import "Point3.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. +(id)created
  22. {
  23. Point2 *p = [[Point2 alloc] init];
  24. return p;
  25. }
  26. +(id)createdWithX:(int)x andY:(int)y
  27. {
  28. Point2 *p = [[Point2 alloc] initWithX:x andY:y];
  29. return p;
  30. }
  31. -(void)show
  32. {
  33. NSLog(@"x=%d,y=%d", _x, _y);
  34. }
  35. @end

步骤四:在主程序中使用Point2类

首先在Day02工程中新添加Point3Main.m文件,用于存储主程序,在主程序中创建两个Point2类的对象,一个用无参工厂方法创建,另一个用有参工厂方法创建,最后打印这两个对象。

代码如下所示:

  1. #import "Point3.h"
  2. int main(int argc, const char * argv[])
  3. {
  4. @autoreleasepool {
  5. // insert code here...
  6. Point2 *p = [Point2 created];
  7. [p show];
  8. Point2 *p1 = [Point2 createdWithX:55 andY:77];
  9. [p1 show];
  10. }
  11. return 0;
  12. }

2.3 完整代码

本案例中,类Point2声明,即Point3.h文件,完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface Point2 : NSObject
  3. {
  4. }
  5. @property int x, y;
  6. -(id)init;
  7. -(id)initWithX:(int)x andY:(int)y;
  8. +(id)created;
  9. +(id)createdWithX:(int)x andY:(int)y;
  10. -(void)show;
  11. @end

类Point2实现,即Point3.m文件,完整代码如下所示:

  1. #import "Point3.h"
  2. @implementation Point2
  3. -(id)init
  4. {
  5. if (self = [super init])
  6. {
  7. _x = 10;
  8. _y = 20;
  9. }
  10. return self;
  11. }
  12. -(id)initWithX:(int)x andY:(int)y
  13. {
  14. if (self = [super init])
  15. {
  16. _x = x;
  17. _y = y;
  18. }
  19. return self;
  20. }
  21. +(id)created
  22. {
  23. Point2 *p = [[Point2 alloc] init];
  24. return p;
  25. }
  26. +(id)createdWithX:(int)x andY:(int)y
  27. {
  28. Point2 *p = [[Point2 alloc] initWithX:x andY:y];
  29. return p;
  30. }
  31. -(void)show
  32. {
  33. NSLog(@"x=%d,y=%d", _x, _y);
  34. }
  35. @end

主程序,即Point3Main.m,完整代码如下所示:

  1. #import "Point3.h"
  2. int main(int argc, const char * argv[])
  3. {
  4. @autoreleasepool {
  5. // insert code here...
  6. Point2 *p = [Point2 created];
  7. [p show];
  8. Point2 *p1 = [Point2 createdWithX:55 andY:77];
  9. [p1 show];
  10. }
  11. return 0;
  12. }