Objective

在前面, 我们认识了什么是构造方法, 构造方法是不是固定就只有一种呢? 其实不是的, 我们也可以自己定义构造方法, 利用我们自己定义的构造方法来完成更多的功能, 或者说提高我们的编程效率, 下面让我们一起来探究吧~~


例子:

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property int age;
@end

@implementation Person
- (id)init
{
    if (self = [super init])
    {
	_age = 10;
    }
    return self;
}
@end

int main()
{
    Person *p = [[Person alloc]init];
	
    return 0;
}



这是我们上一节学的构造方法, 功能比较单一, 就直接初始化了一种, 而且并不能随我们的意愿去改变, 下面让我们来看看改良后的构造方法, 也就是我们自己定义的构造方法:

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property int age;

- (id)initWithAge:(int)age;
@end

@implementation Person
- (id)init
{
    if (self = [super init])
    {
	_age = 10;
    }
    return self;
}
- (id)initWithAge:(int)age
{
    if (self = [super init])
    {
	_age = age;
    }
    return self;
}

@end

int main()
{
    Person *p = [[Person alloc]init];
	
    Person *p1 = [[Person alloc]initWithAge:30];

    return 0;
}



这个就是我们改良后的构造方法, 可以在外界自行决定, 这样的好处就是不用管里面是怎么实现的, 你也不需要那.m文件给你的同事, 让他知道你是怎么实现的.



并且我们自定义的构造方法是可以传入多个参数, 比如:

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property int age;
@property NSString *name;

- (id)initWithAge:(int)age;
@end

@implementation Person
- (id)init
{
    if (self = [super init])
    {
	_age = 10;
    }
    return self;
}
- (id)initWithAge:(int)age andName:(NSString *)name
{
    if (self = [super init])
    {
	_age = age;
	_name = name;
    }
    return self;
}

@end

int main()
{
    Person *p = [[Person alloc]init];
	
    Person *p1 = [[Person alloc]initWithAge:30 andName:@"Jim"];

    return 0;
}

PS:但自定义的构造方法命名要有一定的规范, 一定要以initWith开头, 否则会被公司直接开除.






有人或许会问, 那么在继承方面呢?? 我们来看看~~~

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property int age;
@property NSString *name;

- (id)initWithAge:(int)age;
@end

@implementation Person
- (id)init
{
    if (self = [super init])
    {
	_age = 10;
    }
    return self;
}
- (id)initWithAge:(int)age andName:(NSString *)name
{
    if (self = [super init])
    {
	_age = age;
	_name = name;
    }
    return self;
}
@end

@interface Student : Person
@property int number;
- (id)initWithNumber:(int)number;
@end

@implementation Student
- (id)initWithNumber:(int)number
{
    if (self = [super init])
    {
	_number = number;
    }
    return self;
}
@end

int main()
{
    Person *p = [[Person alloc]init];
	
    Person *p1 = [[Person alloc]initWithAge:30 andName:@"Jim"];

    return 0;
}



在继承上我们也可以这么写, 但如果要把父类的成员变量也要写上, 那么得改一点东西~~比如:

@interface Student : Person
@property int number;
- (id)initWithNumber:(int)number andName:(NSString *)name andAge:(int)age;
@end

@implementation Student
- (id)initWithNumber:(int)number andName:(NSString *)name andAge:(int)age
{
	if (self = [super init])
	{
		_number = number;
		self.name = name;
		self.age = age;
	}
	return self;
}
@end

我们都知道, 如果不特定去写@public的话, 那么默认就是@protected, 所以不能直接去访问, 只能通过set方法间接去访问, 但在我们实际开发的时候, 这么写是不太好的, 那么该怎么写呢? 下面让我们来看看~~


@interface Student : Person
@property int number;
- (id)initWithNumber:(int)number andName:(NSString *)name andAge:(int)age;
@end

@implementation Student
- (id)initWithNumber:(int)number andName:(NSString *)name andAge:(int)age
{
    if (self = [super initWithAge:age andName:name])
    {
	_number = number;

    }
    return self;
}
@end

那么这么写的好处有什么呢?

1. 子类的事情子类做, 不用管父类做什么, 我直接把age和name传给父类的initWithAge: andName方法, 让它自己改变.

2. 一旦父类里面的某个成员变量名改变了, 子类完全可以不用去理会.



这个涉及一些我们设计模式, 在这里我唠叨一下, 我们在写代码的时候, 必须得知道我们写了这么一行代码对我们后面的开发会不会造成有不好的影响, 比如上面的例子, 如果我不用最后的这个方法来写, 那如果父类的name这个成员变量名改变了, 我们子类也要跟着去改变, 这无形之中不就会增加我们的工作量了么? 而运用好设计的思想, 子类与父类又关联, 但又相互独立, 就好像老爸和儿子一样, 老爸去工作, 儿子去上学, 两者之间有一定的关联, 但又是相互的独立个体, 这就是造物者的设计模式, 在编程中我们也要有这样子的设计模式, 才能让我们成为更加优秀的程序员, 而不是一个简简单单的码农.




好了, 这次我们就讲到这里, 下次我们继续~~~~

原文地址:https://www.cnblogs.com/iOSCain/p/4282838.html