一、OC方法
(一)对象方法
(1)对象方法以-开头,如 - (void)xx;
(2)对象方法只能用对象来调用
(3)对象方法中可以访问当前对象的成员变量
(4)调用格式 [对象名 对象方法名];
(5)设计一个学生类和狗类,练习对象方法的使用。
学生类的声明:
1 // 设计一个学生类,学生的属性包括:性别、生日、体重、最喜欢的颜色、狗(体重、 毛色、吃) 2 // 方法:吃、跑步、遛狗、喂狗 3 #import <Foundation/Foundation.h> 4 @class Dog; 5 6 /** 7 定义枚举类型,学生性别 8 */ 9 typedef enum { 10 sexMale, // 男性 11 SexFemale // 女性 12 }Sex; 13 14 /** 15 * 定义结构体:生日 16 */ 17 typedef struct { 18 int year; 19 int month; 20 int day; 21 }Date; 22 23 typedef enum { 24 ColorBlack, 25 ColorRed, 26 ColorGreen 27 }Color; 28 29 30 @interface Student : NSObject 31 { 32 @public 33 NSString *name; // 姓名 34 Sex sex; // 性别 35 Date birthday; // 生日 36 double weight; // 体重 37 Color favColor; // 喜欢的颜色 38 Dog *dog; 39 } 40 41 - (void)eat; 42 - (void)run; 43 - (void)print; 44 - (void)weiDog; 45 - (void)liuDog;
学生类的实现:
1 #import "Student.h" 2 #import "Dog.h" 3 4 @implementation Student 5 6 - (void)eat 7 { 8 weight += 1; 9 NSLog(@"人吃完这次后的体重是%d", weight); 10 } 11 12 - (void)run 13 { 14 weight -= 1; 15 NSLog(@"人跑完这次后的体重是%d", weight); 16 } 17 18 - (void)print 19 { 20 NSLog(@"姓名 = %@, 性别 = %d, 喜欢的颜色 = %d, 生日 = %d-%d-%d", name, sex, favColor, birthday.year, birthday.month, birthday.day); 21 } 22 23 - (void)weiDog 24 { 25 // 在学生类对象的对象方法中调用狗对象的对象方法 26 [dog eat]; 27 } 28 29 - (void)liuDog 30 { 31 [dog run]; 32 } 33 34 @end
狗类的声明:
#import <Foundation/Foundation.h> @interface Dog : NSObject { @public double weight; } - (void)eat; - (void)run; @end
狗类的实现:
1 #import "Dog.h" 2 3 @implementation Dog 4 5 - (void)eat 6 { 7 weight += 1; 8 NSLog(@"狗吃完这次后的体重是%f", weight); 9 } 10 11 - (void)run 12 { 13 weight -= 1; 14 NSLog(@"狗跑完这次后的体重是%f", weight); 15 } 16 17 @end
主程序:
#import <Foundation/Foundation.h> #import "Student.h" #import "Dog.h" int main(int argc, char * argv[]) { // 创建一个学生类对象 Student *stu = [[Student alloc] init]; // 对学生类对象的一些属性进行初始化 stu -> name = @"Zeng"; stu -> sex = sexMale; stu -> favColor = ColorBlack; Date date = {1989, 7, 22}; stu -> birthday = date; stu -> weight = 110; // 创建一个狗对象 Dog *dog = [[Dog alloc] init]; dog -> weight = 8; stu -> dog = dog; // 调用学生类的对象方法 [stu print]; [stu run]; [stu eat]; // 调用狗对象类的对象方法 [dog eat]; [dog run]; [stu weiDog]; [stu liuDog]; return 0; }
(二)类方法
(1)类方法以+开头 如+(void)put;
(2)类方法只能由类来调用
(3)类方法中不能访问实例(成员)变量,因为类方法又类来调用,并没有创建存储空间来存储类中的成员变量。
(4)调用格式:[类名 类方法名];
(5)类方法的好处和适用场合:
不依赖于对象,执行效率更高;
能用类方法解决的问题,尽量使用类方法;
场合:当方法内部不需要使用到成员变量时,可以改为类方法。
(6)设计一个计算器类,练习使用类方法。
计算器类的声明:
1 // 实现一个简单的计算器工具类,实现一个类方法,计算三个整数的和。 2 #import <Foundation/Foundation.h> 3 4 @interface JiSuanQi : NSObject 5 6 // 工具类一般没有成员变量 7 + (int)sumOfNumber1:(int)num1 andNumber2:(int)num2 andNumber3:(int)num3; 8 9 @end
计算器类的实现:
1 // 计算器类方法的实现 2 #import "JiSuanQi.h" 3 4 @implementation JiSuanQi 5 6 + (int)sumOfNumber1:(int)num1 andNumber2:(int)num2 andNumber3:(int)num3 7 { 8 return num1 + num2 + num3; 9 } 10 11 @end
主程序:直接使用类名调用类方法
1 #import <Foundation/Foundation.h> 2 #import "JiSuanQi.h" 3 4 int main(int argc, char * argv[]) { 5 6 int a = [JiSuanQi sumOfNumber1:10 andNumber2:20 andNumber3:30]; 7 NSLog(@"a和为%d", a); 8 9 int b = [JiSuanQi sumOfNumber1:100 andNumber2:200 andNumber3:300]; 10 NSLog(@"b和为%d", b); 11 12 return 0; 13 }
注意1:可以允许类方法和对象方法同名。
注意2:在对象方法中可以调用类方法。
(三)方法名
(1)不带参数的方法
声明:
调用:
(2)带参数的方法
声明:
调用:
注意:冒号也是方法名的一部分。
二、文件编译
在工作中,通常把不同的类放到不同的文件中,每个类的声明和实现分开,声明写在.h头文件中,实现写在相应的.m文件中去,类名是什么,文件名的前缀就是什么。
假设有两个类,分别是Person类和Dog类,则通常有下面五个文件:
(1)Person.h Person类的声明文件
(2)Person.m Person类的实现文件
(3)Dog.h Dog类的声明文件
(4)Dog.m Dog类的实现文件
(5)Main.m 主函数(程序入口)
在主函数以及类的实现文件中要使用#import包含相应的头文件。
补充:import有两个作用:一是和include一样,完完全全的拷贝文件的内容;二是可以自动防止文件内容的重复拷贝(即使文件被多次包含,也只拷贝一份)。
在使用命令行进行编译链接文件的时候,通常是把.m文件单文件编译,然后再把所有的目标文件链接,但是在Xcode中,是把所有的.m文件都进行编译链接的,如果出现重复定义的错误,那大部分问题根源应该就是文件内容被重复包含或者是包含.m文件所引起的。
源文件中不论是使用include还是import,都不能包含.m或者是.c文件,只能放声明。因此,在OC中通常把类拆分开来,拆分成声明和实现两个部分。
提示:这也是编程思想的一种体现,可以说.h和.m文件时完全独立的,只是为了要求有较好的可读性,才要求两个文件的文件名一致,这也是把接口和实现分离,让调用者不必去关心具体的实现细节。
Xcode是写一行编译一行,有简单的修复功能,红色是错误提示,黄色警告。如果在程序中声明了一个变量,但是这个变量没有被使用也会产生警告信息。在调试程序的时候,如果发现整个页面都没有报错,但是一运行就错误,那么一定是链接报错。