一.类学习引入
//缺点 _result的结果一直在变化,得创建变量,在堆区一直申请空间
<span style="font-size:14px;">#import<Foundation/Foundation.h>
#import"Calculator.h"
int main(intargc,const char* argv[]) {
@autoreleasepool {
Calculator *cl = [Calculator new];
cl->_num1= 10;
cl->_num2= 3 ;
//加法
[cl add];
NSLog(@"%.2f",cl->_result);
//减法
[cl minus];
NSLog(@"%.2f",cl->_result);
//乘法
[cl mulpti];
NSLog(@"%.2f",cl->_result);
//除法
[cl division];
NSLog(@"%.2f",cl->_result);
}
return 0;
}</span>
<span style="font-size:14px;">#import<Foundation/Foundation.h>
@interface Calculator :NSObject
{
@public ;
int _num1,_num2;
float _result;
}
-(void)add;
-(void)minus;
-(void)mulpti;
-(void)division;
@end
#import"Calculator.h"
@implementationCalculator
-(void)add{
_result = _num1+_num2;
}
-(void)minus{
_result = _num1-_num2;
}
-(void)mulpti{
_result = _num1*_num2;
}
-(void)division{
if(_num2!=0)
_result = _num1/(float)_num2;
else
NSLog(@"被除数不能为0");
}
@end</span>
方法2
//改进方法在堆区的空间小了,没有在声明对象时候创建变量
<span style="font-size:14px;">#import<Foundation/Foundation.h>
#import"Calculator2.h"
//代码在堆区的空间小了节省内存
int main(intargc,const char* argv[]) {
@autoreleasepool {
Calculator2 *c2 =[Calculator2 new];
int result = [c2 add:13 andNum2:3];
NSLog(@"%d",result);
result = [c2 minus:13 andNum2:3];
NSLog(@"%d",result);
}
return 0;
}</span>
<span style="font-size:14px;">#import<Foundation/Foundation.h>
@interface Calculator2 :NSObject
{
@public ;
}
-(int)add:(int)num1 andNum2 :(int) num2;
-(int)minus :(int)num1 andNum2 :(int) num2;
-(int)mulpti :(int)num1 andNum2 :(int) num2;
-(float)division:(int)num1 andNum2 :(int) num2;;
@end
#import"Calculator2.h"
@implementationCalculator2
-(int)add:(int)num1 andNum2 :(int) num2{
return num1 + num2;
}
-(int)minus :(int)num1 andNum2 :(int) num2{
return num1 - num2;
}
-(int)mulpti :(int)num1 andNum2 :(int) num2{
return num1 * num2;
}
-(float)division:(int)num1 andNum2 :(int) num2{
if(num2!=0)
return num1 / (float)num2;
else
{
NSLog(@"被除数不能为0");
return 1.f ;
}
}
@end</span>
2).类方法
1.不依赖于任何对象
2.类方法和对象方法可以重名(本质是类型不同)
3.类方法只能被向类方法发送消息,向实例对象发送类方法是不能被触发的
4.在类方法里使用self,self执行类对象classobject,而不是实例对象instanceobject
5.节省内存空间
6.作为工具方法
7.提高效率()
3).类方法易犯错误
类方法中不能调用实例变量
类方法和对象方法的比较
对象方法:
1.‘-’开头
2.对象方法可以在对象方法中调用其他对象方法
3.可以使用self
4.对象作为方法的参数传递过来,可以使用传递过来的对象调用方法
4).类方法
1.可以直接使用其他类名调用其他类方法
2.可以在类方法中调用本类的类方法
3.使用self
4.类方法中可以调用对象方法(通过将对象作为参数传递过来)
2).或者在类中创建新的对象
6).类方法不能调用自身类方法
(如果再在main.m中调用此类方法,会导致无限循环)
<span style="font-size:14px;">#import<Foundation/Foundation.h>
#import"Calculator.h"
int main(intargc,const char* argv[]) {
@autoreleasepool {
Calculator *cal = [Calculator new];
int result = [cal add:13 andNum2:34];
NSLog(@"result= %d",result);
//类方法调用 //节省内存,堆区不需要创建对象,不需要分配存储空间
result = [Calculatoradd:13 andNum2:34];
NSLog(@"result= %d",result);
}
return 0;
}</span>
<span style="font-size:14px;">#import<Foundation/Foundation.h>
@interface Calculator :NSObject
{
@public ;
}
-(int)add:(int)num1 andNum2 :(int) num2;
-(int)minus :(int)num1 andNum2 :(int) num2;
-(int)mulpti :(int)num1 andNum2 :(int) num2;
-(float)division:(int)num1 andNum2 :(int) num2;;
//类方法
+(int)add:(int)num1 andNum2 :(int) num2;
+(int)minus :(int)num1 andNum2 :(int) num2;
+(int)mulpti :(int)num1 andNum2 :(int) num2;
+(float)division:(int)num1 andNum2 :(int) num2;;
@end
#import"Calculator.h"
@implementationCalculator
-(int)add:(int)num1 andNum2 :(int) num2{
return num1 + num2;
}
-(int)minus :(int)num1 andNum2 :(int) num2{
return num1 - num2;
}
-(int)mulpti :(int)num1 andNum2 :(int) num2{
return num1 * num2;
}
-(float)division:(int)num1 andNum2 :(int) num2{
if(num2!=0)
return num1 / (float)num2;
else
{
NSLog(@"被除数不能为0");
return 1.f ;
}
}
+(int)add:(int)num1 andNum2 :(int) num2{
return num1 + num2;
}
+(int)minus :(int)num1 andNum2 :(int) num2{
return num1 - num2;
}
+(int)mulpti :(int)num1 andNum2 :(int) num2{
return num1 * num2;
}
+(float)division:(int)num1 andNum2 :(int) num2{
if(num2!=0)
return num1 / (float)num2;
else
{
NSLog(@"被除数不能为0");
return 1.f ;
}
}
@end</span>
7).类方法应用场景
1.调用一个方法,该方法不需要使用成员变量,那么可以声明为类方法
2.没有创建对象,堆区是空的,成员变量没有分配内存空间,无法使用,没办法存储代码区的变量值,没有意义。所以类中不能访问成员变量
<span style="font-size:14px;">#import<Foundation/Foundation.h>
#import"IPhone.h"
int main(intargc,const char* argv[]) {
@autoreleasepool {
NSString *str = [IPhone getPhoneColor:KColorTHJ];
NSLog(@"手机颜色为: %@",str);
}
return 0;
}
#import<Foundation/Foundation.h>
typedefenum{KColorWhite,KColorBlack,KColorTHJ} Color;
@interface IPhone :NSObject
{
@public;
Color _color;
}
+(NSString *)getPhoneColor:(Color)color;
@end
#import"IPhone.h"
@implementation IPhone
+(NSString *)getPhoneColor:(Color)color{
NSString *colorName ;
switch (color) {
case KColorWhite:
colorName =@"白色";
break;
case KColorBlack:
colorName =@"黑色";
break;
case KColorTHJ:
colorName =@"金色";
break;
default:
break;
}
return colorName ;
}
@end</span>
8).匿名类的概念,如何访问成员变量,调用方法
<span style="font-size:14px;">#import<Foundation/Foundation.h>
#import"Car.h"
int main(intargc,const char* argv[]) {
@autoreleasepool {
Car *car1 =[Carnew] ;
//[Car new] 实质上理解为对象的存储空间返回的是一个地址_isa
//使用[Car new ]和car1是一样的
//匿名类 (匿名对象)时候用
//匿名类访问实例变量(能,只能访问一次,以后再访问是新的空间)
[Carnew]->_speed =250;//0x10
NSLog(@"_speed= %d ",[Carnew]->_speed);//0
//NSLog中又[Car new]一次地址变为 0x20所以访问的时候返回的为0
//匿名类,可以调用方法
[[Carnew]stop];//对象方法
[[[Caralloc]init]stop];//等价于 [Carnew]返回地址
}
return 0;
}
#import<Foundation/Foundation.h>
@interface Car :NSObject
{
@public
int _speed ;
}
-(void)start;
-(void)stop;
+(void)start;
+(void)stop;
@end
#import"Car.h"
@implementation Car
-(void)start{
NSLog(@"对象方法:车已经启动,正准备以%d的速度启动",_speed);
}
-(void)stop{
NSLog(@"对象方法:车停了");
}
+(void)start{
NSLog(@"类方法:车已经启动,正准备以的速度启动");
}
+(void)stop{
NSLog(@"类方法:车停了");
}
@end</span>
9).拷贝两个文件后看是否文件存在,确保.m文件在compliesources中
<span style="font-size:14px;">#import<Foundation/Foundation.h>
#import"Person.h"
int main(intargc,const char* argv[]) {
@autoreleasepool {
Person *p = [[Person alloc] init];
Car *car1 = [Carnew];
car1->_speed = 80 ;
[p goHome:car1];
//匿名类作为方法的参数使用
[pgoHome:[Carnew]];// 0要以80的速度只能定义对象
//匿名类调用匿名方法
[[Personnew ]goHome:[Carnew]];
}
return 0;
}</span>
匿名对象缺点:匿名对象实例化后,只能正确的使用成员变量一次
封装:隐藏底层数据的复杂
<span style="font-size:14px;">#import<Foundation/Foundation.h>
@interface Gun:NSObject{
int _bullietCount;
}
-(void)shoot;
-(void)setBulletCount:(int)bulletCount;
@end
@implementation Gun
-(void)shoot{
if (_bullietCount> 0 ) {
_bullietCount--;
NSLog(@"tututu子弹剩余数 :%d",_bullietCount);
}
else{
NSLog(@"没有子弹");
}
}
-(void)setBulletCount:(int)bulletCount{
if (bulletCount>0) {
_bullietCount = bulletCount;
}
}
@end
int main(intargc,const char* argv[]) {
@autoreleasepool {
Gun *gun = [Gunnew];
[gun setBulletCount:1];
[gun shoot];
[gun shoot];
[gun shoot];
}
return 0;
}</span>
1)settle方法 (设置器)
考虑到安全性,通过set方法对成员变量进行设置
命名规范
1)方法名必须set开头
2)set后面跟成员变量名称,首字母大写setAge
3)返回值一定是void
4)一定要接收一个参数,而且参数类型需要和成员变量类型一致
5)形参名不能和成员变量名一样通过_区分
Get方法也是一个对象方法(getter访问器)
1)一定有返回值
2)返回值类型和实例变量的类型一致
3)方法名和成员变量名一样(成员变量名去掉下划线)
4)不需要接收任何参数
<span style="font-size:14px;">#import<Foundation/Foundation.h>
#import"Person.h"
int main(intargc,const char* argv[]) {
@autoreleasepool {
Person *p1 = [Person new ];
[p1setName:@"李云迪"];
[p1 setAge:20];
[p1 setHeight:178.3];
[p1 setSex:KSexMan];
NSLog(@"%@的身高是:%f,性别:%d,年龄:%d",[p1name],[p1height],
[p1 sex],[p1 age]);
}
return 0;
}
#import<Foundation/Foundation.h>
typedefenum{KSexMan,KSexFemale} Sex;
@interface Person :NSObject{
NSString *_name;
int _age ;
Sex _sex ;
float _height;
}
-(void)setName:(NSString*)name;
-(void)setAge:(int)age;
-(void)setSex:(Sex)sex;
-(void)setHeight:(float)height;
-(NSString *)name;
-(int)age;
-(Sex)sex;
-(float)height;
@end
#import"Person.h"
@implementation Person
-(void)setName:(NSString*)name{
_name = name ;
}
-(void)setAge:(int)age{
_age = age ;
}
-(void)setSex:(Sex)sex{
_sex = sex ;
}
-(void)setHeight:(float)height{
_height = height ;
}
-(NSString *)name{
return _name ;
}
-(int)age{
return _age ;
}
-(Sex)sex{
return _sex ;
}
-(float)height{
return _height;
}
@end</span>
二、封装应用股票K线的计算
OC没有接口概念,有协议的概念
一串葡萄单个葡萄
对象之间的关系组合模式
三、依赖对象
高内聚也叫高耦合
#import<Foundation/Foundation.h>
#import"Girl.h"
int main(intargc,const char* argv[]) {
@autoreleasepool {
//girl依赖iphone7对象
IPhone *ip7 =[IPhone new];
Girl *girl = [Girl new];
[girl callPhoneTo:ip7];
[girl sendMsg:ip7];
}
return 0;
}
#import<Foundation/Foundation.h>
@interface IPhone :NSObject
{
NSString *_phoneNumber ;
}
-(void)setPhoneNumer:(NSString*) phoneNumber;
//打电话发短信
-(void)callPhone;
-(void)sendMsg;
@end
#import"IPhone.h"
@implementation IPhone
-(void)setPhoneNumer:(NSString*) phoneNumber{
_phoneNumber = phoneNumber;
}
//打电话发短信
-(void)callPhone{
NSLog(@"给土豪%@打电话",_phoneNumber);
}
-(void)sendMsg{
NSLog(@"给土豪%@发短信",_phoneNumber);
}
@end
#import<Foundation/Foundation.h>
#import"IPhone.h"
@interface Girl :NSObject
-(void)callPhoneTo:(IPhone *)iphone;
-(void)sendMsg:(IPhone*) iphone ;
@end
#import"Girl.h"
@implementation Girl
-(void)callPhoneTo:(IPhone *)iphone{
[iphone setPhoneNumer:@"19833232"];
[iphone callPhone];
}
-(void)sendMsg:(IPhone*) iphone {
[iphone setPhoneNumer:@"19833232"];
[iphone sendMsg];
}
@end
2).关联关系
HasA关系:当一个对象拥有另一个对象的时候(如人必须有一条狗才能遛狗)
#import<Foundation/Foundation.h>
#import"Person.h"
int main(intargc,const char* argv[]) {
@autoreleasepool {
IPad *ip5 = [IPadnew];
[ip5 setName:@"IPAD5"];
Person *p1 = [Person new];
[p1 setIPad:ip5];
[p1 listenMusic];
}
return 0;
}
#import<Foundation/Foundation.h>
#import"IPad.h"
@interface Person :NSObject
{
NSString * _name ;
IPad *_ipad ;//IPad对象
}
//设置姓名和ipad
-(void)setName:(NSString*)name;
-(void)setIPad:(IPad*)ipad ;
//听音乐的方法
-(void)listenMusic;
@end
#import"Person.h"
@implementation Person
//设置姓名和ipad
-(void)setName:(NSString*)name{
_name = name ;
}
-(void)setIPad:(IPad*)ipad {
_ipad = ipad;
}
//听音乐的方法
-(void)listenMusic{
[_ipadplayMusic];
}
@end
#import<Foundation/Foundation.h>
@interface IPad :NSObject
{
NSString *_name ;
}
-(void)setName:(NSString*)name;
-(void)playMusic;
-(void)playMovie;
-(void)playGame;
@end
#import"IPad.h"
@implementation IPad
-(void)setName:(NSString*)name{
_name = name ;
}
-(void)playMusic{
NSLog(@"正在使用%@播放音乐",_name);
}
-(void)playMovie{
NSLog(@"正在使用%@播放电影",_name);
}
-(void)playGame{
NSLog(@"正在使用%@玩游戏",_name);
}
@end
可以的,后面的冒号前面可以不写东西
4).OC中使用static关键字
OC中实例变量不能设置为静态变量
没有初始化的静态变量存在BSS段
已经初始化的静态变量存在数据区C中
OC中局部变量也是满足上部分
如果是类里的实例变量,不能用static
/Users/chingwei_macpc/Documents/OC-第三第四天/OC-static关键字/Dog.m:13:5:Type name does not allow storage class to be specified
Static也不能修饰一个类或对象方法
OC中静态全局变量只能在当前文件中使用,其他文件中不能使用此变量
两个类文件不能同名staticint变量名。
在同时import到main中的时候会报错