------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -----
第一讲 类方法学习引入
本小节知识点:
1、【了解】类方法学习思考
2、【了解】实现OC版计算器
思考&实现1:
设计一个“计算器(Calculator)”类
1)实现两个书的 + - * / 的计算
思考:
首先创建一个类
类名:Calculator
属性:第一个数 num1 第二个数 num2 运算结果 result
1 #import <Foundation/Foundation.h> 2 //第一种方法 3 @interface Caculator : NSObject 4 { 5 @public 6 //定义实例变量 7 int _num1; 8 int _num2; 9 float _result; 10 } 11 //四个方法 12 -(void)add; 13 -(void)jian; 14 -(void)cheng; 15 -(void)chu; 16 @end 17 #import "Caculator.h" 18 19 @implementation Caculator 20 -(void)add{ 21 _result = _num1 +_num2; 22 23 } 24 -(void)jian{ 25 _result = _num1 -_num2; 26 } 27 -(void)cheng{ 28 29 _result = _num1 *_num2; 30 } 31 -(void)chu{ 32 33 _result = _num1 /(float)_num2; 34 } 35 @end 36 37 //第二种方法 声明类 38 @interface Calculator2 : NSObject 39 //四个方法 40 -(int)add:(int) num1 andNum2:(int) num2; 41 -(int )jian:(int) num1 andNum2:(int) num2; 42 -(int)cheng:(int) num1 andNum2:(int) num2; 43 -(float)chu:(int) num1 andNum2:(int) num2; 44 @end 45 46 #import "Calculator2.h" 47 48 @implementation Calculator2 49 //四个方法 50 -(int)add:(int) num1 andNum2:(int) num2{ 51 return num1 + num2; 52 } 53 -(int)jian:(int) num1 andNum2:(int) num2{ 54 return num1 - num2; 55 56 } 57 -(int)cheng:(int) num1 andNum2:(int) num2{ 58 return num1 * num2; 59 } 60 -(float)chu:(int) num1 andNum2:(int) num2{ 61 return num1 /(float) num2; 62 } 63 @end 64 65 66 #import <Foundation/Foundation.h> 67 #import "Caculator.h" 68 #import "Calculator2.h" 69 int main(int argc, const char * argv[]) 70 { 71 72 @autoreleasepool { 73 74 // //创建对象 75 // Caculator *cal = [Caculator new]; 76 // cal->_num1 = 10; 77 // cal->_num2 = 3; 78 // 79 // //加法 80 // [cal add]; 81 // NSLog(@"%.2f",cal->_result); 82 // [cal jian]; 83 // NSLog(@"%.2f",cal->_result); 84 // [cal cheng]; 85 // NSLog(@"%.2f",cal->_result); 86 // [cal chu]; 87 // NSLog(@"%.2f",cal->_result); 88 89 //第二种方法 90 Calculator2 *c2 = [Calculator2 new]; 91 92 int result = [c2 add:12 andNum2:34]; 93 int result2 = [c2 cheng:3 andNum2:10]; 94 NSLog(@"%d",result); 95 NSLog(@"%d",result2); 96 } 97 return 0; 98 99 }
第二讲 类方法的调用
本小节知识点:
1、【理解】类方法概述
2、【理解】类方法的调用
Objective-C中的类可以声明两种类型的方法:实例方法和类方法。
1、类方法概述
实例方法就是一个方法,它在类的一个具体实例的范围内执行。也就是说,在你调用一个实例方法前,你必须首先创建类的一个实例。(也叫对象方法)
[对象名 对象方法名];
而类方法,比较起来,也就是说,不需要你创建一个实例。
+表示类方法,就是类调用方法,不依赖与任何对象的方法。
-表示是实例(对象)方法,只能是对象可调用,依赖与任何对象的方法。
2、类方法的调用
[类名称 类方法名称];
#import <Foundation/Foundation.h>
@interface Caculator : NSObject
//四个方法
-(int)add:(int) num1 andNum2:(int) num2;
-(int )jian:(int) num1 andNum2:(int) num2;
-(int)cheng:(int) num1 andNum2:(int) num2;
-(float)chu:(int) num1 andNum2:(int) num2;
//四个方法
+(int)add:(int) num1 andNum2:(int) num2;
+(int )jian:(int) num1 andNum2:(int) num2;
+(int)cheng:(int) num1 andNum2:(int) num2;
+(float)chu:(int) num1 andNum2:(int) num2;
@end
#import "Caculator.h"
@implementation Caculator
//四个方法对象方法
-(int)add:(int) num1 andNum2:(int) num2{
return num1 + num2;
}
-(int)jian:(int) num1 andNum2:(int) num2{
return num1 - num2;
}
-(int)cheng:(int) num1 andNum2:(int) num2{
return num1 * num2;
}
-(float)chu:(int) num1 andNum2:(int) num2{
return num1 /(float) num2;
}
//类方法的实现
//四个方法
+(int)add:(int) num1 andNum2:(int) num2{
return num1 + num2;
}
+(int)jian:(int) num1 andNum2:(int) num2{
return num1 - num2;
}
+(int)cheng:(int) num1 andNum2:(int) num2{
return num1 * num2;
}
+(float)chu:(int) num1 andNum2:(int) num2{
return num1 /(float) num2;
}
@end
1 /* 2 类方法: 3 4 +开头的方法(定义的过程和对象方法一致,只不过 + 开头) 5 6 类方法的调用: 7 8 [类名 方法名]; 9 10 对比学习: 11 Dog类 12 -(void)run; 13 想调用 run方法, 14 1. Dog *dog = [Dog new]; 15 16 [dog run]; 17 18 Dog类 19 20 +(void)run; //类方法 21 22 想调用run方法, 23 [Dog run]; 24 */ 25 26 27 #import <Foundation/Foundation.h> 28 #import "Caculator.h" 29 int main(int argc, const char * argv[]) 30 { 31 32 @autoreleasepool { 33 Caculator *ca1 = [Caculator new]; 34 //通过ca1对象调用其对象方法 35 int result = [ca1 add:23 andNum2:34]; 36 37 NSLog(@"result = %d",result); 38 //通过类名调用类方法 39 result = [Caculator add:10 andNum2:20]; 40 NSLog(@"result = %d",result); 41 42 43 } 44 return 0; 45 }
第三讲 类方法的使用注意事项
【理解】类方法的使用注意事项
1、类方法可以和实例方法同名,这个并不影响使用,实例方法由实例对象访问调用,类方法要通过类里访问调用,不会有交叉相互影响。
2、类方法也可以是从父类继承而来,子类可以重写类方法,如description类方法就可以在子类里重新定义这个方法。
3、类方法和实例方法一样在interface里声明,在implementation里实现
4、类方法只能被向类发送类方法消息才被执行,向实例对象发送类方法是不能被触发执行的。
5、在类方法里使用了self,这个self执行的类对象class object而不是实例对象instance object
1 #import <Foundation/Foundation.h> 3 @interface Dog : NSObject 6 -(void)run; 7 +(void)run; 8 +(void)eat:( NSString *)foodName; 9 10 @end 11 12 #import "Dog.h" 13 14 @implementation Dog 15 -(void)run{ 16 NSLog(@"对象方法 ------- 狗正在疯跑!"); 18 } 19 +(void)run{ 20 NSLog(@"类方法 --- 狗正在疯跑!"); 22 } 23 +(void)eat:(NSString *)foodName{ 24 25 NSLog(@"狗正在吃%@",foodName); 26 } 28 @end 31 #import <Foundation/Foundation.h> 32 #import "Dog.h" 33 int main(int argc, const char * argv[]) 34 { 35 36 @autoreleasepool { 37 Dog *dog = [Dog new]; 38 [dog run]; //对象方法 39 [Dog run]; //类方法 40 41 [Dog eat:@"一根热乎乎的热狗"]; 42 } 43 return 0; 44 }
第四讲 类方法易犯的错误
本小节知识点:
1、【理解】类方法的优点
2、【掌握】类方法的易犯错误
3、【理解】类方法和对象方法的比较
1、类方法的优点:
1)节省内存空间
2)提高了效率
3)作为工具方法
2、类方法的易犯错误
1、在类方法中使用了类的成员变量
//通过类方法实现两个数的平均值
+(float) avgNum1:(int)num1 andNum2:(int)num2{
//调用类方法计算两个数的和
return -result/2.0f; // 注意: 类方法中不能使用类的成员变量
}
//通过实例方法实现两个数的平均值
-(float)avg{
//调用类方法计算两个数的和
return _result/2.0f; //注意:在实例方法中可以使用类的成员变量
}
3、类方法与对象方法比较
1)对象方法:
以 - 号开头
可以使用成员变量
用对象调用对象方法
对象方法可以调用当前对象或者其他对象的方法(是通过将对象作为参数传入方法)
1 #import <Foundation/Foundation.h> 2 #import "Dog.h" 3 4 @interface Car : NSObject 5 { 6 @public 7 int _speed; 8 } 9 -(void)run; 10 -(void)test; 11 +(void)run; 12 +(void)run:(int)speed; 13 +(void)test:(Dog *)dog; 14 +(void)t1; 15 @end 16 17 // 18 19 #import "Car.h" 20 21 @implementation Car 22 -(void)run{ 23 24 NSLog(@"车正在以%d码的速度跑",_speed); 25 //对象方法中可以调用其他的对象方法 26 //1)当前对象方法中创建对象(可以是当前类的实例对象,也可以是其他类的实例对象),使用新创建的对象调用对象方法 27 // Car *car1 = [Car new]; 28 // [car1 test]; 29 // 其他的实例对象 30 // Person *p = [Person new]; 31 // [p eat]; 32 //2)可以使用self 33 [self test]; 34 //3)对象作为方法的参数传递过来,可以使用传递过来的对象调用方法 35 36 } 37 -(void)test{ 38 39 NSLog(@"test------"); 40 } 41 +(void)run{ 42 ///Volumes/VMware Shared Folders/自学视频基础笔记/视频第十八天的课程/OC6-类方法易犯错误/Car.m:17:44: Instance variable ‘_speed‘ accessed in class method 43 44 //类方法里面访问了实例变量,这是不允许的, 45 // NSLog(@"车正在以%d码的速度跑",_speed); 46 NSLog(@"类方法---车正在跑"); 47 48 //在类方法中可以调用其他类方法 49 //1)可以直接使用本类类名(或者其他类名)调用类方法 50 [Car run:250]; 51 [Dog run]; 52 //可以使用self吗? 53 [self run:100]; 54 55 } 56 +(void)run:(int)speed{ 57 NSLog(@"类方法---车正在以%d码的速度跑",speed); 58 59 } 60 +(void)test:(Dog *)dog{ 61 62 //在类方法中可以调用对象方法 63 //1)对象作为方法的参数传递过来 64 //2)可以创建一个对象 65 Dog *d1 = [Dog new]; 66 [d1 eat]; 67 68 [dog eat]; 69 } 70 71 +(void)t1{ 72 73 //类方法可以调用其他类方法 74 //类方法不能调用自身 75 76 // NSLog(@"Car的类方法 t1"); 77 // [Car t1]; //自己调用自己 无限循环 78 } 79 @end 80 81 82 2)类方法: 83 以+开头 84 不可以使用成员变量 85 用类名调用类方法 86 类方法可以调用对象方法(是通过将对象作为参数传入方法)和类方法 87 类方法不可以调用自身,会造成死循环 88 89 #import <Foundation/Foundation.h> 90 91 @interface Dog : NSObject 92 { 93 94 } 95 +(void)run; 96 -(void)eat; 97 98 @end 99 100 #import "Dog.h" 101 102 @implementation Dog 103 +(void)run{ 104 NSLog(@"狗正在疯跑"); 105 } 106 -(void)eat{ 107 108 NSLog(@"狗正在吃"); 109 } 110 @end 111 112 #import <Foundation/Foundation.h> 113 #import "Car.h" 114 int main(int argc, const char * argv[]) 115 { 116 117 @autoreleasepool { 118 //对象方法调用 119 Car *car = [Car new]; 120 car->_speed = 200; 121 [car run]; //实例方法调用 122 //类方法调用 123 [Car run]; 124 [Car run:50]; //对象作为方法的参数传递过来 125 126 //类方法用对象方法调用 127 Dog *d1 = [Dog new]; 128 [Car test:d1]; //狗正在吃 129 130 // [Car t1]; 类方法调用自己 无限循环 131 } 132 return 0; 133 }
第五讲 类方法应用场景
本小节知识点:
【理解】OC类方法应用场景
1、OC类方法应用场景
如果我们调用一个方法,该方法中不需要使用成员变量,那么我们可以将该方法声
明为类方法。
[Car run];
练习:
有一个手机的类iPhone,该类中有一个枚举类型的实例变量_color
kColorBlack 黑色 kColorWhtie 白色 kColorTHJ 土豪金
1)请定义一个类方法,实现返回真实手机颜色,而非枚举值。
//+(NSString *)getPhoneColor:(Color)color;
1 #import <Foundation/Foundation.h> 3 typedef enum {kColorBlack,kColorWhite,kColorTHJ}Color; 4 @interface IPhone : NSObject 5 { @public 6 Color _color; 8 } 9 +(NSString *)getPhoneColor:(Color)color; 10 @end 11 12 #import "IPhone.h" 13 14 @implementation IPhone 15 +(NSString *)getPhoneColor:(Color)color{ 16 17 NSString *colorName; 18 //根据color的值做判断 19 // 0 1 2 20 //kColorBlack kColorWhite kColorTHJ 21 switch (color) { 22 case kColorBlack: 23 colorName = @"黑色"; 24 break; 25 case kColorWhite : 26 colorName = @"白色"; 27 break; 28 case kColorTHJ: 29 colorName = @"土豪金"; 30 break; 32 default: 33 break; 34 } 35 return colorName; 36 } 37 @end 38 39 #import <Foundation/Foundation.h> 40 #import "IPhone.h" 41 int main(int argc, const char * argv[]) 42 { 44 @autoreleasepool { 47 NSString *str = [IPhone getPhoneColor:kColorTHJ]; 48 NSLog(@"%@",str); 49 } 50 return 0; 51 }
第六讲 匿名类的概念及使用
本小节知识点:
1、【了解】匿名类的概念
2、【理解】匿名类访问成员变量
3、【理解】匿名类调用方法
1、匿名类的概念
1 #import <Foundation/Foundation.h> 2 3 @interface Car : NSObject 4 { 5 @public 6 int _speed; 7 } 8 -(void)start; 9 -(void)stop; 10 @end 11 12 #import "Car.h" 13 14 @implementation Car 15 -(void)start{ 16 17 NSLog(@"车已经启动,正准备以%d的速度跑",_speed); 18 } 19 -(void)stop{ 20 21 NSLog(@"咯吱,车停了"); 22 } 23 @end 24 25 #import <Foundation/Foundation.h> 26 #import "Car.h" 27 int main(int argc, const char * argv[]) 28 { 29 30 @autoreleasepool { 31 32 // 创建对象 33 Car *car1 = [Car new]; 34 35 car1->_speed = 100; 36 37 //找到栈区,找到堆区, 找到代码区 38 [car1 start]; 39 40 //[Car new]; 实质上对象的存储空间 41 42 //匿名类(匿名对象)时候用 43 //1、使用匿名类访问实例变量(能,只能访问一次) 44 //以后再次访问,实际上访问新的空间了 45 [Car new]->_speed = 250; 46 NSLog(@"_speed = %d",[Car new]->_speed); // 0 47 48 //2、使用匿名 的类,可以调用方法 49 // 50 [[Car new] stop]; //可以 51 52 // 3、 申请空间 初始化 53 [[Car alloc] init]; //等价于 [Car new]; 54 55 //使用alloc init 的方式调用 stop方法 56 [[[Car alloc] init] stop]; 57 58 } 59 return 0; 60 }
2、匿名类作为方法的参数
本小节知识点:
1、【掌握】匿名类作为方法的参数
2、【了解】匿名类的优缺点
1 #import <Foundation/Foundation.h> 2 3 @interface Car : NSObject 4 { 5 @public 6 int _speed; 7 } 8 -(void)start; 9 -(void)stop; 10 @end 11 12 #import "Car.h" 13 14 @implementation Car 15 -(void)start{ 16 17 NSLog(@"车已经启动,正准备以%d的速度跑",_speed); 18 } 19 -(void)stop{ 20 21 NSLog(@"咯吱,车停了"); 22 } 23 @end 24 25 #import <Foundation/Foundation.h> 26 #import "Car.h" 27 @interface Person : NSObject 28 { 29 30 } 31 -(void)goHome:(Car *)car; 32 @end 33 34 #import "Person.h" 35 36 @implementation Person 37 -(void)goHome:(Car *)car{ 38 39 //人开车回家,实质是车跑 40 [car start]; 41 } 42 43 @end 44 45 #import <Foundation/Foundation.h> 46 #import "Person.h" 47 int main(int argc, const char * argv[]) 48 { 49 50 @autoreleasepool { 51 52 Person *p = [[Person alloc] init ]; 53 //创建一个车 54 Car *car = [Car new]; 55 car->_speed = 80; 56 // [p goHome:car]; 57 58 //1、匿名类作为方法的参数使用 59 // [p goHome:[Car new]]; 60 61 //匿名类调用方法,参数又是匿名类 62 [[Person new] goHome:[Car new]]; //0 63 } 64 return 0; 65 }
2、匿名类优缺点
优点:可以简化代码,方便方法调用
缺点:匿名对象实例化以后,只能正确的使用成员变量一次
常见用法:
//下面两句的作用是等价的
Person *p = [[Person alloc] init];
Person *p1 = [Person new];
两者的区别:
alloc 和 init 分别把分配内存和初始化的工作分开。这样更加的灵活,可以自行初始
化对象的成员变量值
而不像new每次都初始化为0
new 是吧分配内存和初始化的工作一起完成了,先分配内存,然后调用类的构造函
数。