黑马程序员——OC基础学习(二)---对象方法和类方法的学习知识总结

时间:2023-02-17 09:39:49



------  <a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a> 期待与您交流! -------


一.对象方法的学习知识总结


 1.定义:

         在oc中方法声明写在@interface...@end中间,方法实现写在@implementation...@end中间,并以"-"号开头的方法,称为对象方法.

 2.特点:

  •         以"-"开头;
  •         只能由对象调用;
  •         对象方法归类\对象所有.
 3.语法:        (1)声明语法:                 -(方法的返回值类型) 方法名;------不带参数的                  例:-(void) sum;
                -(方法的返回值类型) 方法名:(参数的类型)参数的名称;------带一个参数的                  例:-(void) sum: (int) a;
                -(方法的返回值类型) 方法名:(参数的类型)参数的名称 and方法名: 参数类型;------带多个参数的                  例:-(void) sum: (int) a andSum: (int) b;
         (2)实现语法:                -(方法的返回值类型) 方法名{
                    语句1;                     语句2;                     ...
                }------不带参数的                 例:-(void) sum{                      语句1;                      语句2;                      ...                   }
                -(方法的返回值类型) 方法名:(参数的类型)参数的名称{                                            语句1;                      语句2;                      ...
                  }------带一个参数的                 例:-(void) sum: (int) a{                                   语句1;                         语句2;                         ...
                    }
                -(方法的返回值类型) 方法名:(参数的类型)参数的名称 and方法名: 参数类型{
                                                                    语句1;                                               语句2;                                               ...                   }------带多个参数的                 例:-(void) sum: (int) a andSum: (int) b{
                                                语句1;                         语句2;                         ...                   }
  4.对象方法的调用
                   [对象名  对象方法名];  
  5.常见错误汇总
     (1)@interface...@end和@implementation...@end不能嵌套包含;        (2)只有声明没有实现;        (3)漏写@end;        (4)把声明写在{}里面了;        (5)方法不能像函数那样调用.
 6.对象和对象方法之间的关系    (1)对象作为对象方法的参数                  例:
          假设有Person类:Person类有name、sex属性

           假设实例化Person的对象

           Person *p = [Person new];

           p->name ="凤姐";

           p->sex = "女";

           ............

-(void) displayPerson:(Person *)person{

NSLog("姓名:%@",person->name);

NSLog("姓名:%@",person->sex);

}............


(2)对象作为对象方法的返回值

     例:           

-(Person*)changePerson:(Person*)person{

person->name=@"张三";

person->sex=@"男";

person->age = 28;

return person;

}


Person *P2 = [d changePerson:p1];

[d displayPerson:p2];


  7.对象作为对象方法的参数---实际应用

/*

要求设计一个”狗“类
 1> 属性
 * 颜色
 * 速度(单位是m/s)
 * 性别
 * 体重(单位是kg)
 
 2> 行为
 * 吃:每吃一次,体重增加0.5kg,输出吃完后的体重
 * 吠(叫):输出所有的属性
 * 跑:每跑一次,体重减少0.5kg,输出速度和跑完后的体重
 * 比较颜色:跟别的狗比较颜色,如果一样,两个值做减法得零,相同,YES,不等于0,颜色不相同,返回值NO
 * 比较速度:跟别的狗比较速度,返回速度差(自己的速度 - 其他狗的速度)

*/


#import <Foundation/Foundation.h>

#pragma mark 狗类的声明

// Color 是 enum c 别名
//定义颜色的枚举类型
typedef enum c{kColorBlack,kColorWhite,kColorYellow,kColorTHJ} Color;

//定义性别的枚举类型
typedef enum s{kSexGong,kSexMu,kSexYao} Sex;

@interface Dog : NSObject
{
@public
//颜色使用枚举
Color _color; //狗毛的颜色
int _speed; //狗的速度

Sex _sex; //狗的性别
float _weight; //狗的体重

}

//
-(void)eat;
-(void)run;
-(void)bark;
//比较狗毛的颜色
-(BOOL)compareColorWithOther:(Dog *) dog;
//计算两条狗的速度差
-(int)compareSpeedWithOther:(Dog *) dog;

@end

#pragma mark 狗类的实现
@implementation Dog

-(void)eat{

//每吃一次 +0.5
_weight += 0.5f;

//吃东西,吃完以后,输出体重
NSLog(@"狗吃完后的体重是%.2f",_weight);

}
-(void)run{

//每跑一次 -0.5
_weight -= 0.5f;

//输出速度和体重
NSLog(@"狗正在以%d的速度向前疯跑,体重是%.2f",_speed,_weight);

}
-(void)bark{

//输出各个属性
NSLog(@"颜色:%d,速度:%d,性别:%d,体重:%.2f",_color,_speed,_sex,_weight);

}

//比较狗毛的颜色
-(BOOL)compareColorWithOther:(Dog *) dog{

//比较狗毛的颜色
//当前狗的颜色 _color 另外一条狗 dog->_color
//相同 YES
//不相同 NO
if (_color == dog->_color) {
return YES;
}else{

return NO;
}
}

//计算两条狗的速度差
-(int)compareSpeedWithOther:(Dog *) dog{

//dog->_speed 另外一条狗的速度

return _speed - dog->_speed;

}
@end

int main(int argc, const char * argv[]) {
@autoreleasepool {

//创建一个对象
Dog *d = [Dog new];
d -> _color = kColorTHJ;
d -> _speed = 120;
d -> _sex = kSexGong;
d -> _weight = 60.45f;

[d eat];
[d bark];
[d run];

//创建另外一条狗
Dog *other = [Dog new];
other -> _color = kColorTHJ;
other -> _speed = 100;
other -> _sex = kSexMu;
other -> _weight = 40.45f;


//比较两个狗的颜色
BOOL isSame = [d compareColorWithOther:other];
if (isSame) {

NSLog(@"颜色相同");

}else{

NSLog(@"颜色不同");

}


//比较速度
int s = [d compareSpeedWithOther:other];
NSLog(@"速度差:%d",s);

}
return 0;
}

  8.对象作为对象方法的返回值---实际应用

/**

综合示例(包含对象作为对象方法的参数和对象作为对象方法的返回值)

*/

#import <Foundation/Foundation.h>

//狗这个类的声明
@interface Dog : NSObject
{
@public
int _speed;
NSString *_name;
}

//显示狗的信息
-(void)dispDog:(Dog *)dog;
-(Dog *)changeSpeed:(Dog*)dog;

@end


//狗这个类的实现

@implementation Dog
-(void)dispDog:(Dog *)dog{

NSLog(@"狗的名称:%@,速度:%d",dog->_name,dog->_speed);

}


-(Dog *)changeSpeed:(Dog*)dog{

//修改速度
dog -> _speed = 252; //byd speed 252

return dog; // byd

}
@end



int main(int argc, const char * argv[]) {
@autoreleasepool {

//创建一个对象
Dog *d = [Dog new];
d->_speed = 100;
d->_name = @"花花";

Dog *byd = [Dog new];
byd ->_name = @"大黄";
byd ->_speed = 250;

//查看 byd 对象 的信息
[d dispDog:byd];
[byd dispDog:d];

//jd存储byd的地址,jd等同于byd
Dog *jd = [d changeSpeed:byd];
[d dispDog:jd];
[d dispDog:byd];

}
return 0;
}




二.类方法的学习知识总结

 

 1.定义:

       在oc中方法声明写在@interface...@end中间,方法实现写在@implementation...@end中间,并以"+"号开头的方法,称为类方法. 

  

  2.特点:

  •         以"+"开头;
  •         只能由类来调用;
  •         不依赖任何对象.
    3.语法:       (1)声明语法:                +(方法的返回值类型) 方法名;------不带参数的                 例:+(void) sum;
                +(方法的返回值类型) 方法名:(参数的类型)参数的名称;------带一个参数的                 例:+(void) sum: (int) a;
                +(方法的返回值类型) 方法名:(参数的类型)参数的名称 and方法名: 参数类型;------带多个参数的                 例:+(void) sum: (int) a andSum: (int) b;
         (2)实现语法:               +(方法的返回值类型) 方法名{
                    语句1;                    语句2;                    ...
                }------不带参数的                 例:+(void) sum{                      语句1;                      语句2;                      ...                   }
                +(方法的返回值类型) 方法名:(参数的类型)参数的名称{                                            语句1;                      语句2;                      ...
                  }------带一个参数的                 例:+(void) sum: (int) a{                                   语句1;                         语句2;                         ...
                    }
                +(方法的返回值类型) 方法名:(参数的类型)参数的名称 and方法名: 参数类型{
                                                                    语句1;                                               语句2;                                               ...                   }------带多个参数的                 例:+(void) sum: (int) a andSum: (int) b{
                                                语句1;                         语句2;                         ...                   }

   4.类方法的调用
                   [类名  类方法名];


  5.类方法使用注意事项
    (1)类方法可以和实例方法同名,这个并不影响使用;      (2)类方法可以从父类继承而来,也可以重写类方法;      (3)类方法和对象方法一样,在@interface里声明,在@implementation里实现;      (4)类方法只能被类调用执行;      (5)在类方法里使用self,这个self执行的类对象class object,而不是实例对象instance object.
  6.类方法与对象方法比较 
     (1)类方法
               以+开头                    不可以使用成员变量                    用类名调用类方法                     类方法可以调用对象方法(是通过将对象作为参数传入方法)和类方法                    类方法不可以调用自身,会造成死循环 
           (2)对象方法
               -号开头                    可以使用成员变量                    用对象调用对象方法对象方法可以调用当前对象或者其他对象的方法(是通过将对象作为参数传入方法) 

7.类方法的应用---一个小程序
/*

有一个手机的类iPhone,该类中有一个枚举类型的实例变量_color

kColorBlack 黑
kColorWhite 白
kColorTHJ 土豪金

请定义一个类方法,实现返回真实手机颜色,而非枚举值。

(注:为使代码整清晰可见,这里把.h和.m里的代码放到一起.)

*/

#import <Foundation/Foundation.h>

//定义一个枚举类型,并且起别名为 iColor
typedef enum {kColorBlack,kColorWhite,kColorTHJ} iColor;

@interface IPhone : NSObject
{

//有一个枚举类型的实例变量 ,表示颜色
iColor _color;

}

// 给一个枚举值,返回该枚举值对应的真实的颜色
+(NSString *)getPhoneColor:(iColor) color;
@end




#import "IPhone.h"
@implementation IPhone
//类方法的实现
+(NSString *)getPhoneColor:(iColor) color{

// color 0 1 2

NSString *colorName;

//分支语句,做判断
switch (color) {
case kColorBlack:
colorName = @"黑色";
break;
case kColorWhite:

colorName = @"白色";
break;

case kColorTHJ:
colorName = @"土豪金";
break;

}

return colorName;

}
@end




#import <Foundation/Foundation.h>
#import "IPhone.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {

//调用类方法,实现返回手机的真实颜色
NSString *str = [IPhone getPhoneColor:kColorWhite];
NSLog(@"%@",str);


}
return 0;
}





三.类的本质 


  1.类的本质

类的本质其实也是一个对象(类对象)

类对象

*类对象再程序运行时一直存在。

*类对象是一种数据结构,存储类的基本信息:类大小,类名称,类的版本以及消息与函数的映射表等

*类对象所保存的信息在程序编译时确定,在第一次使用该类的时候被加载到内存中

*类对象代表类,class代表类对象,类方法属于类对象

*如果消息的接收者是类名,则类名代表类对象

*运行时,所有类的实例都由类对象生成,类对象会把实例的isa的值修改

 成自己的地址,每个实例的isa都指向该实例的类对象

*从类对象里可以知道父类信息、可以响应的方法等

*类对象只能使用类方法,不能用实例方法 

2.类类型的变量(实例对象)

Person *p = [Person new];

//把类的代码加载到代码区

//产生一个类对象,类型是Class  isa指向代码区的Person类

//实例化对象三件事

//申请空间 初始化 返回地址

//对象isa 指向类对象 


//p 是实例对象

//Person 也是一个对象(类对象),是Class类型 


3.类对象(类名)如何获取

1)通过实例对象获取

类对象获取   [实例对象名  class];

2)通过类名获取(类名其实就是类对象)

类对象获取    [类名  class];

   4.类对象的用法


         1)可以用来调用方法

         2)可以用来实例化实例对象