------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ———
类和对象的使用
1、对象的存储细节
类创建对象,每个对象在内存中都占据一定的存储空间,每个对象都有一份属于自己的单独的成员变量,所有的对象公用类的成员方法,方法在整个内存中只有一份,类本身在内存中占据一份存储空间,类的方法存储于此。
每一个对象都包含一个isa指针,这个指针指向当前对象所属的类。
[p eat];表示给p所指向的对象发送一条eat消息,调用对象的eat方法,此时对象会顺着内部的isa指针找到存储于类中的方法,执行。
isa是对象中的隐藏指针,指向创建这个对象的类。
在OC中存在一个名为id的类型,这个和上面所说这个isa指针有一定的联系。
C代码
typedef struct objc_object {
Class isa;
} *id;
其中class类型为指向objc_class结构体的指针类型。
这些对象在内存中都是由其地址唯一标示,所有的对象都是id类型的。
2、使用一个类创建多个对象
Car *car2 = [Car new];
Car *car3 = [Car new];
当使用一个类创建多个对象的时候,注意:
1)不同的对象在内存中分配的是不同的存储地址,所以各成员属性的地址也各不相同
3、函数和对象方法的区别
对象方法:
(1)对象方法的实现只能写在@implementation...@end中,对象方法的声明只能写在@interface...@end中间
(2)对象方法都是以-号开头,类方法都是以+开头
(3)对象方法只能由对象来调用,类方法只能由类来调用,不能单做函数一样调用
(4)函数属于整个文件,可以写在文件中的任何位置,包括@implementation...@end中,但写在@interface...@end会无法识别,函数的声明可以在main函数内部也可以在main函数外部。
(5)对象方法归类\对象所有
函数:
(1)所有的函数都是平行的
(2)函数不存在隶属关系
(3)使用的时候可以直接调用
(4)不可以访问对象中的成员变量
4、常见错误
(1)@interface @end和@implementation @end不能嵌套包含
OC是弱语法,可以只有@implementation,但实际开发中千万不要这样
(2)只有类的声明没有类的实现
只有@interface没有@implementation时,程序编译能够通过,但是执行报错,错误如下:
(3)漏泄@end
(4)两个类的对象声明顺序(可以把顺序打乱)
(5)成员变量没有写在{}里
(6)方法的声明写在了{}里
(7)在声明时不能对类的成员变量进行初始化,请注意成员变量不能脱离对象而独立存在
(8)方法无法像函数那样的调用
(9)成员变量和方法不能用static等关键字修饰,不要和c语言混淆
(10)类的实现可以写在main函数后面,在使用之前只要声明就可以
5、对象和方法之间的关系
(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 = person->age + 1;
return person;
}
Person *p2 = [d changePerson:p1];
[d displayPerson:p2];
(3)对象作为方法的参数连续传递
实现功能:士兵开枪 枪射击子弹
枪类:
名称:Gun
属性:型号(_size),子弹个数(_bulletCount)
行为:射击
人类:
名称:Soldier
属性:姓名(_name) life level(等级)
行为:跑 蹲 开枪 跳
/*
士兵开枪 枪射击子弹
枪类:
名称:Gun
属性:型号(_size),子弹个数(_bulletCount)
行为:射击
人类
名称:Soldier
属性:姓名(_name) life level(等级)
行为:跑 蹲 开枪 跳
*/
#import <Foundation/Foundation.h>
#pragma mark 枪类声明
@interface Gun:NSObject
{
//实例变量
@public
NSString *_size; //枪的型号
int _bulletCount; //枪的子弹数
}
//行为
-(void)shoot;
@end
#pragma mark 枪类实现
@implementation Gun
-(void)shoot{
NSLog(@"%@ 正在 突突的射击...",_size);
}
@end
#pragma mark 士兵类声明
@interface Soldier:NSObject
{
@public
NSString *_name;
int life;
int level;
// Gun *_gun;
}
//行为
//士兵开火
-(void)fireByGun:(Gun *) gun;
@end
#pragma mark 士兵类实现
@implementation Soldier
-(void)fireByGun:(Gun *) gun{
//让枪射击
//gun 不为 null
[gun shoot];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建一个士兵对象
Soldier *s = [Soldier new];
s->_name = @"三多";
s->life = 98;
s->level = 2;
//创建枪的对象
Gun *gun = [Gun new];
gun->_size = @"小米加步枪";
gun->_bulletCount = 3;
//士兵开枪
[s fireByGun:gun];
[s fireByGun:gun];
[s fireByGun:gun];
}
return 0;
}
/*
士兵开枪 枪射击子弹
枪类:
名称:Gun
属性:型号(_size),子弹个数(_bulletCount)
行为:射击
人类
名称:Soldier
属性:姓名(_name) life level(等级)
行为:跑 蹲 开枪 跳
*/
#import <Foundation/Foundation.h>
#pragma mark 枪类声明
@interface Gun:NSObject
{
//实例变量
@public
NSString *_size; //枪的型号
int _bulletCount; //枪的子弹数
}
//行为
-(void)shoot;
@end
#pragma mark 枪类实现
@implementation Gun
-(void)shoot{
//每射击一次,子弹的个数要-1
if(_bulletCount>0){
_bulletCount --;
NSLog(@"\n%@ 正在 突突的射击...,剩余子弹:%d",_size,_bulletCount);
}else{
NSLog(@"\n没有子弹还突突个毛线!");
}
}
@end
#pragma mark 士兵类声明
@interface Soldier:NSObject
{
@public
NSString *_name;
int life;
int level;
// Gun *_gun;
}
//行为
//士兵开火
-(void)fireByGun:(Gun *) gun;
@end
#pragma mark 士兵类实现
@implementation Soldier
-(void)fireByGun:(Gun *) gun{
//让枪射击
//gun 不为 null
[gun shoot];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建一个士兵对象
Soldier *s = [Soldier new];
s->_name = @"三多";
s->life = 98;
s->level = 2;
//创建枪的对象
Gun *gun = [Gun new];
gun->_size = @"小米加步枪";
gun->_bulletCount = 3;
//士兵开枪
[s fireByGun:gun];
[s fireByGun:gun];
[s fireByGun:gun];
[s fireByGun:gun];
[s fireByGun:gun];
[s fireByGun:gun];
}
return 0;
}
/*
士兵开枪 枪射击子弹
枪类:
名称:Gun
属性:型号(_size),子弹个数(_bulletCount)
行为:射击
人类
名称:Soldier
属性:姓名(_name) life level(等级)
行为:跑 蹲 开枪 跳
子弹类(弹夹)
名称:Bullet
属性:子弹个数,型号(_model)
//要求士兵在射击的时候,不但要给一把枪,还要给 一个弹夹才能射击
//子弹不能为负数
*/
#import <Foundation/Foundation.h>
#pragma mark 子弹类的声明
@interface Bullet:NSObject
{
@public
NSString *_size;
int _bulletCount;
}
@end
#pragma mark 子弹类的实现
@implementation Bullet
@end
#pragma mark 枪类声明
@interface Gun:NSObject
{
//实例变量
@public
NSString *_size; //枪的型号
}
//枪的行为
-(void)shoot:(Bullet *) bullet;
@end
#pragma mark 枪类实现
@implementation Gun
//枪射击的方法的实现
-(void)shoot:(Bullet *) bullet{
//判断子弹数>0
//子弹对象(弹夹)中的子弹的个数
if(bullet->_bulletCount>0){
//子弹数-1
bullet->_bulletCount --;
NSLog(@"啪啪啪...枪在射击...剩余子弹:%d",bullet->_bulletCount);
}else{
//如果子弹数<0 提示没子弹了
NSLog(@"没子弹了,请换子弹");
}
}
@end
#pragma mark 士兵类声明
@interface Soldier:NSObject
{
@public
NSString *_name;
int life;
int level;
// Gun *_gun;
}
//行为
-(void)fireByGun:(Gun *) gun andBullet:(Bullet *)bullet;
@end
#pragma mark 士兵类实现
@implementation Soldier
-(void)fireByGun:(Gun *) gun andBullet:(Bullet *)bullet{
//让枪装上子弹,然后射击
//子弹作为参数传递给射击的方法
[gun shoot:bullet];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建一个士兵对象
Soldier *s = [Soldier new];
s->_name = @"三多";
s->life = 98;
s->level = 2;
//创建枪的对象
Gun *gun = [Gun new];
gun->_size = @"小米加步枪";
//创建子弹
Bullet *myBullet = [Bullet new];
myBullet->_size = @"5mm口径";
myBullet->_bulletCount = 3;
[s fireByGun:gun andBullet:myBullet];
[s fireByGun:gun andBullet:myBullet];
[s fireByGun:gun andBullet:myBullet];
[s fireByGun:gun andBullet:myBullet];
}
return 0;
}