方法(二)
方法
Oc分为两种方法,
一种是类方法,用 + 号来表示,形式为:[类名 方法名],表现为:+(instancetype) alloc;
一种是实例方法,用 – 号来表示,形式为:[对象名 方法名],表现为:-(void)setName;
注意的是,类方法实现中,不能使用实例变量。因为在类方法中,并没有分配内存,没有实例变量的位置,所以不允许使用。
一个例子:
Person.h文件
#import <Foundation/Foundation.h> @interface Person : NSObject{ NSString *_name;
}
//方法声明 //无参无返回值 //类方法 + (void) sayHi; //实例方法 - (void)sayBye; - @end |
Person.m文件
#import "Person.h" @implementation Person //类方法
+ (void) sayHi{ NSLog(@"sayHI"); //错误: //类方法中,不能使用实例变量,因为不会分配内存给实例变量。 // NSLog(@"%@",_name); } //实例方法 - (void)sayBye{ NSLog(@"sayBye"); NSLog(@"%@",_name); } @end
|
main.m文件
#import <Foundation/Foundation.h> #import "Person.h"
int main(int argc, const char * argv[]) { //2015年04月14日10:44:12 北京 @autoreleasepool { //类方法的调用 //类名调用 //没有分配内存 [Person sayHi];//2015-04-14 10:48:32.545 OCLesson2_方法[1075:43549] sayHI // [Person sayBye];//方法类型不匹配,报错
//实例方法 //用对象来调用 //分配内存了 Person *p1 = [[Person alloc]init]; [p1 sayBye];//2015-04-14 10:51:14.553 OCLesson2_方法[1093:44531] sayBye
//OC是使用消息发送机制,说 调方法是不准确的。 //调方法,是必须执行 //消息发送机制,有请求的意思,这个消息不一定能执行。 } return 0; } |
方法的声明:
类方法和实例方法的声明形式一样,因此只写一种。
无参无返回值:
//无参无返回值
- (void) backName; |
- 号表示实例方法,backName表示方法名,(void )表示返回值类型为空。
无参有返回值:
- (NSString *) backName; |
- 号表示实例方法,backName表示方法名,(NSString *)表示返回值类型为字符串类型。
有参无返回值:
//有参无返回值 //writeName:是方法名(包括冒号) //在方法中,类型都是用括号()括起来的。(void)和(NSString *)。 //判断方法中有几个参数,就看参数就看方法名有几个冒号。 //name 为变量名 - (void)writeName:(NSString *)name;//一个参数 |
- 号表示实例方法,writeName:表示方法名(注意,这里包括冒号:也就是整个writeName:都是方法名)。(NSString *)表示参数的类型是字符串类型,name表示参数名。整个来读,就是实例方法writeName:,返回值为空,有一个参数,参数类型是字符串型,参数名为name。
有参有返回值:
//方法名是testName:testAge:(都要包括冒号:) //第一个参数name之前:描述这个方法是干什么的 + 第一个参数的描述 //第二个参数age之前,描述第二个参数是干什么的(可以不写) + 第二个参数的描述 - (void)testName:(NSString *)name age:(NSInteger)age;//两个参数 //方法名是testName:testAge:(都要包括冒号:) //第一个参数name之前:描述这个方法是干什么的 + 第一个参数的描述 //第二个参数age之前,描述第二个参数是干什么的(可以不写) + 第二个参数的描述 - (void)testName:(NSString *)name age:(NSInteger)age;//两个参数
//三个参数 //方法名:testName:age:testSex: //见名之意 - (void) testName:(NSString *)name age:(NSInteger)age testSex:(NSString *)sex; // 冒号 : 就可以作为方法名 //参数前面可以不加描述 //这个方法的方法名是 ::: //不建议省去描述 - (void) :(NSString *)name :(NSInteger)age :(NSString *)sex;
//有参有返回值 - (NSString *) writeName:(NSString *)name age:(NSInteger)age sex:(NSString *)sex; |
方法的声明,最陌生的是参数。
方法名与之前C语言声明的方法名不同,这里的方法名,包括冒号。方法名中得描述可以省去,只留下冒号,这些冒号连起来就是方法名。
参数个数,看冒号有多少个,就有多少个参数,一个方法里,所有的类型都用小括号()括起来。
自定义初始化方法init+。。。
在oc中,若要自定义初始化方法,必须遵循一定的法则:
1、必须在.h文件中声明;
2、返回值类型为(instancetype);
3、必须以init开头,后面跟着的单词第一个字符必须大写;如initWithName
4、参数按照实例方法的参数声明。
5、如果不按照以上的法则,则声明出来的方法不是初始化方法,而是普通方法。
例子:
Person.h文件
#import <Foundation/Foundation.h> @interface Person : NSObject{
NSString *_name; NSInteger _age; } //初始化方法(自定义的) //必须在.h文件中声明 //必须使用init开头,并且init后的第一个字母必须大写。 - (instancetype)initWithName:(NSString*)name age:(NSInteger)age;//初始化方法 //普通方法 - (void) writeWithName:(NSString*)name age:(NSInteger)age;//普通方法 @end |
Person.m文件
#import "Person.h" @implementation Person //初始化方法实现 - (instancetype)initWithName:(NSString*)name age:(NSInteger)age{ //不完整,还差了继承的东西 _name = name; _age = age; //初始化方法必须return self; return self; } //给实例变量赋值 - (void) writeWithName:(NSString*)name age:(NSInteger)age{ _name = name; _age = age; } @end |
main.m文件
#import <Foundation/Foundation.h> #import "Person.h" #import "Student.h" int main(int argc, const char * argv[]) {
@autoreleasepool {
// Person *p = [[Person alloc]init]; // //给p发送writeWithName:age:消息。 // //平时说方法调用 // [p writeWithName:@"张无忌" age:18];
//调用初始化方法 //对于p1来说,不能进行第二次初始化,初始化只能执行一次。 Person *p1 = [[Person alloc]initWithName:@"路费" age:19]; NSLog(@"%@",[p1 name]);//2015-04-14 15:05:23.268 OCLesson2_方法2[1727:95752] 路费 NSLog(@"%ld",[p1 age]);//2015-04-14 15:05:23.269 OCLesson2_方法2[1727:95752] 19
[p1 setName:@"索隆"]; [p1 setAge:20]; NSLog(@"%@",[p1 name]);//2015-04-14 15:13:20.094 OCLesson2_方法2[1758:98459] 索隆 NSLog(@"%ld",[p1 age]);//2015-04-14 15:13:20.095 OCLesson2_方法2[1758:98459] 20 } return 0; }
|
初始化方法只能执行一次,如要再初始化,需要重新声明另一个初始化方法。
getter方法:
getter和setter方法是配套使用的,用来对protected或者private描述的实例变量取值和赋值。
getter方法是获取实例变量的值,方法名就是实例变量名。
Person.h
#import <Foundation/Foundation.h> @interface Person : NSObject{ NSString *_name; NSInteger _age; } //getter方法 //获取实例变量的值 //方法名就是实例变量名 - (NSString*)name; - (NSInteger)age; |
- 号表示实例方法,(NSString*)表示返回值类型是字符串类型的,name表示方法名,其实就是实例变量名。
setter方法:
与getter方法配套使用,用来对实例变量进行赋值。遵守一些规则:
方法名必须以set开头,后面跟着的单词首字母必须大写,返回值类型为空,参数只有一个,参数类型根据实例变量的类型来定。
//setter方法 //设置实例变量的值 //前面一定要有set,并且set后的第一个字母大写 - (void) setName:(NSString *)name; - (void) setAge:(NSInteger)age; |
- 号表示实例方法,(void)表示返回值类型为空,setName:为方法名(包括冒号:),(NSString *)表示参数类型,name表示参数名。
一个例子:
Student.h
#import <Foundation/Foundation.h>
@interface Student : NSObject{
NSString * _name; NSInteger _age; NSString *_num; }
//自定义初始化方法
- (instancetype)initStudent:(NSString *)name age:(NSInteger)age num:(NSString *)num;
//getter,setter方法
//_name - (NSString *)name; - (void)setName:(NSString*)name;
//_age - (NSInteger)age; - (void)setAge:(NSInteger)age;
//_num - (NSString *)num; - (void)setNum:(NSString *)num;
@end |
Student.m
#import "Student.h"
@implementation Student
//自定义初始化方法
- (instancetype)initStudent:(NSString *)name age:(NSInteger)age num:(NSString *)num{ _name = name; _age = age; _num = num; return self; }
//getter,setter方法 //_name - (NSString *)name{ return _name; } - (void)setName:(NSString*)name{ _name = name; } //_age - (NSInteger)age{ return _age; } - (void)setAge:(NSInteger)age{ _age = age; } //_num - (NSString *)num{ return _num; } - (void)setNum:(NSString *)num{ _num = num; }
@end |
main.m文件
#import <Foundation/Foundation.h> #import "Person.h" #import "Student.h" int main(int argc, const char * argv[]) {
@autoreleasepool { Student *s = [[Student alloc ]initWithName:@"王宝强" age:35 num:@"10086"];
NSLog(@"%@",[s name]); NSLog(@"%@",[s num]); NSLog(@"%ld",[s age]);
[s setName:@"薛宝钗"]; [s setAge:22]; [s setNum:@"100010"];
NSLog(@"%@",[s name]); NSLog(@"%@",[s num]); NSLog(@"%ld",[s age]);
} return 0; } |