OC基础--对象做参数在方法间传递

剧情描述:

美国大兵抗把汉阳造 拿着5个弹夹(每个弹夹5发子弹) 带着弟兄们干架 子弹打完了就求救

类:

士兵:

属性: 姓名(_name) 身高(_height) 体重(_weight)

行为: 开枪(fire) 求救(callForHelp)

枪:

属性: 弹夹(_clip) 弹夹数量(_clipNum) 品牌(_model)

行为: 换弹夹(changeClip) 发射子弹(shot)

弹夹:

属性: 子弹数量(_bulletCount)

行为: 装子弹(addBullet)

方法说明:

士兵开枪方法(fire)

参数: 枪 和 弹夹

返回值: 剩余弹夹数量

逻辑: 将弹夹作为参数  调用枪的发射子弹方法(shot) 获得剩余弹夹数

如果剩余弹夹数 == 0 则调用自己的求救方法(callForHelp)

枪发射子弹方法(shot)

参数: 弹夹

返回值: 弹夹数

逻辑: 如果弹夹里的子弹==0 则调用自己的换弹夹的方法获得新弹夹  否则弹夹子弹减1

枪换弹夹方法(changeClip)

参数: 弹夹

返回值: 弹夹数量

逻辑: 将弹夹数量-1(因为已经用了一个了) 如果还有弹夹 则调用弹夹的装子弹方法 否则提示子弹打光了

弹夹装子弹方法(addBullet)

参数: 无

返回值: 弹夹对象

逻辑: 如果弹夹内子弹数量==0 则装5发子弹  然后将弹夹返回

对象去哪了:

士兵开枪接收了枪和弹夹对象  开枪方法中将弹夹对象传入枪的发射子弹方法  发射子弹方法中又将弹夹对象传入换弹夹方法  换弹夹方法中调用这个弹夹对象的加子弹方法  获得一个弹夹对象的返回值  返回的这个弹夹对象 嘿嘿  不好意思 没用到

弹夹类声明文件Clip.h:

/*
 弹夹
 事物名称: 弹夹(Clip)
 属性:子弹数量(_bulletCount)
 行为:装子弹(addBullet)
 */
#import <Foundation/Foundation.h>

@interface Clip : NSObject
{
    @public
    // 子弹数量
    int _bulletCount;
}
//给弹夹装子弹
- (Clip *) addBullet;
@end 

弹夹类实现文件Clip.m:

#import "Clip.h" 

@implementation Clip 

// 给弹夹装子弹  假设装一次 弹夹就少一个(代表换弹夹)  返回弹夹对象其实没被用到
- (Clip *)addBullet{
    if(_bulletCount == 0){
        _bulletCount = 5;
        NSLog(@"clip  新兵蛋子  子弹装好了  你去冲吧  子弹数量:%i", self->_bulletCount);
    }
    return self;
}
@end

枪类声明文件Gun.h:

/*
 枪
 事物名称:枪(Gun)
 属性:大弹夹(_bigClip) , 弹夹数量(_clipNum),  型号(model)
 行为:换弹夹(changeClip) 射击(shot)
 */
#import <Foundation/Foundation.h>
#import "Clip.h" 

@interface Gun : NSObject
{
    @public
    // 弹夹对象
    Clip* _bigClip;
    // 弹夹数量
    int _clipNum;
    // 枪的牌子
    NSString* _model;
}
// 换弹夹方法
- (int) changeClip:(Clip *) newClip;
// 发射子弹方法
- (int) shot:(Clip *) clip;
@end

枪类实现文件Gun.m:

#import "Gun.h" 

@implementation Gun
// 换弹夹方法 接收弹夹对象  返回弹夹数量
- (int)changeClip:(Clip *)clip{
    // 需要换弹夹说明已经用了一个了  弹夹数量 -1
    _clipNum -= 1;
    // 如果还有弹夹 则调用弹夹加子弹的方法
    if (_clipNum > 0) {
        _bigClip = [clip addBullet];
        NSLog(@"gun  装弹完毕 子弹数量:%i 继续干", clip->_bulletCount);
    }
    else{
        NSLog(@"gun 子弹打光了");
    }
    return _clipNum;
}
// 枪发射子弹方法  接收弹夹对象  返回弹夹数量
- (int)shot:(Clip *)clip{
    // 变量存储弹夹数量  (可以不用这个变量  直接使用属性成员)
    int clipNum = _clipNum;
    // 如果弹夹内没子弹了  则调用换弹夹方法
    if (clip->_bulletCount == 0) {
        NSLog(@"gun  友情提示: 大哥 你没子弹了  俺去给你装弹  你先拼会刺刀吧  装好了再通知你  好吗  就这么愉快的决定吧");
        clipNum = [self changeClip:clip];
    }
    // 否则 子弹 -1
    else{
        NSLog(@"gun  子弹 减 1");
        clip->_bulletCount -= 1;
    }
    return clipNum;
}
@end

士兵类声明文件Soldier.h:

/*
 士兵
 事物名称: 士兵(Soldier)
 属性:姓名(name), 身高(height), 体重(weight)
 行为:打枪(fire), 打电话(callPhone)
 */
#import <Foundation/Foundation.h>
#import "Gun.h" 

@interface Soldier : NSObject
{
    @public
    NSString* _name;
    double _height;
    double _weight;
}
- (int) fireWithGun:(Gun*) gun andClip:(Clip *) clip;
- (void) callForHelp;
@end

士兵类实现文件Soldier.m:

#import "Soldier.h" 

@implementation Soldier
// 士兵开枪  接收枪和弹夹两个对象  返回弹夹剩余数
- (int)fireWithGun:(Gun *)gun andClip:(Clip *)clip{
    NSLog(@"soldier  儿子们 孙子们 王八羔子们  都跟我一起上  冲啊  杀鸡鸡~~~");
    // 将弹夹对象传入 调用枪射击的方法
    int remainClipNum = [gun shot: clip];
    // 如果没弹夹了  调用求救方法
    if(0 == remainClipNum){
        [self callForHelp];
    }
    return remainClipNum;
}
- (void)callForHelp{
    NSLog(@"soldier  拐洞拐  我没子弹了 还中弹了  中了好多呢 你是不知道  吓死宝宝了  快来9我吧 等   你哦 么么哒");
}
@end

Main.m:

#import <Foundation/Foundation.h>
#import "Soldier.h" 

int main(int argc, const char * argv[]) {
    // 士兵对象
    Soldier * soldier = [Soldier new];
    soldier->_height = 2.12;
    soldier->_weight = 80;
    soldier->_name = @"美国大兵";
    // 弹夹对象
    Clip * clip = [Clip new];
    clip->_bulletCount = 5;

    // 枪对象
    Gun * gun = [Gun new];
    gun->_bigClip = clip;
    gun->_model = @"汉阳造";
    gun->_clipNum = 5;    

    // 士兵开始干架
    // 保存剩余弹夹数量  如果数量==0 则跳出循环
    int remainClip = 0;
    while (1) {
        // 调用士兵开枪方法  获得剩余弹夹数
        remainClip = [soldier fireWithGun:gun andClip:clip];
        if (!remainClip) {
            break;        }
    }
    return 0;
} 

输出结果:

/*
输出结果:
    应该是循环五次后提示子弹打光了 然后求救  每次循环中发射五颗子弹
  2015-08-27 23:18:37.182 对象做参数传递[892:34503] soldier  儿子们 孙子们 王八羔子们  都跟我一起上  冲啊  杀鸡鸡~~~
  2015-08-27 23:18:37.184 对象做参数传递[892:34503] gun  子弹 减 1
  2015-08-27 23:18:37.184 对象做参数传递[892:34503] soldier  儿子们 孙子们 王八羔子们  都跟我一起上  冲啊  杀鸡鸡~~~
  2015-08-27 23:18:37.184 对象做参数传递[892:34503] gun  子弹 减 1
  2015-08-27 23:18:37.184 对象做参数传递[892:34503] soldier  儿子们 孙子们 王八羔子们  都跟我一起上  冲啊  杀鸡鸡~~~
  2015-08-27 23:18:37.185 对象做参数传递[892:34503] gun  子弹 减 1
  2015-08-27 23:18:37.185 对象做参数传递[892:34503] soldier  儿子们 孙子们 王八羔子们  都跟我一起上  冲啊  杀鸡鸡~~~
  2015-08-27 23:18:37.185 对象做参数传递[892:34503] gun  子弹 减 1
  2015-08-27 23:18:37.185 对象做参数传递[892:34503] soldier  儿子们 孙子们 王八羔子们  都跟我一起上  冲啊  杀鸡鸡~~~
  2015-08-27 23:18:37.185 对象做参数传递[892:34503] gun  子弹 减 1
  2015-08-27 23:18:37.186 对象做参数传递[892:34503] soldier  儿子们 孙子们 王八羔子们  都跟我一起上  冲啊  杀鸡鸡~~~
  2015-08-27 23:18:37.186 对象做参数传递[892:34503] gun  友情提示: 大哥 你没子弹了  俺去给你装弹  你先拼会刺刀吧  装好了再通知你  好吗  就这么愉快的决定吧
                           ……………
                …………….
                …………….
                …………….
  2015-08-27 23:18:37.217 对象做参数传递[892:34503] gun 子弹打光了
  2015-08-27 23:18:37.217 对象做参数传递[892:34503] soldier  拐洞拐  我没子弹了 还中弹了  中了好多呢 你是不知道  吓死宝宝了  快来9我吧 等你哦 么么哒
*/
时间: 2024-10-10 04:51:49

OC基础--对象做参数在方法间传递的相关文章

OC基础-变量可见对与方法

实例变量的可见度: public(公有的)       实例变量可以在类的外部和内部操作      访问方式:对象名->属性名. protected(受保护的,默认的)    实例变量只能在该类和其子类中操作    访问方式:除类本身和其之类外,其他的不可以直接访问 private(私有的)     实例对象只能在该类访问       访问方式:除本类外不可以直接访问 方法: 类型:类方法,实例方法. 类方法:只能能使用,例如:+(id)alloc ,注意:类方法中不可以使用实例变量. 实例方法

深入理解带参方法-----对象作为参数的方法

在了解过普通的带参方法后,我们再次将视角拉到深入带参方法中. 在数组作为参数的方法里面我们知道了可以将多个学生的成绩添加到数组中并打印出来, 那么如果现在不仅要添加学生的成绩,还要添加学生的年龄和成绩,如何实现呢? 面对这样的问题我们就可以使用面向对象的思想,把所有要添加的学生信息封装到学生类中,只需要在方法中传递一个学生对象就可以包含所有的信息. 接下来就来看看到底应该怎样实现吧. 1 public class Student { 2 //学生类 3 public int id; 4 publ

oc基础第一天---类的方法,类与对象

1. 如何为类定义行为. 刚刚我们聊的是如何为类定义特征. 如何定义行为? 行为就事1个功能 也就事1个函数. OC中把行为叫做方法. 实际上和函数是一样的 代表1个功能模块. 2. 为类定义无参数的方法. 类的方法也分为两个部分. a. 方法的声明 1). 位置: 写在声明类的大括弧的外边. 2). 声明的语法: - (返回值类型)方法名; - (void)sayHi; 这个方法的名字就叫做sayHi; b. 方法的实现. 1). 位置: 写在类的实现之中. 2). 实现的语法: - (返回值

OC基础4:类和方法

1.类的声明(@interface)要放在以它自己名字命名的class.h文件中,而类的定义(@implementation)要放在相同名字的class.m文件中: 2.import本地文件和import系统文件的格式是不同的:导入本地文件要用双引号,导入系统文件要用< 和> :如下: #import <Foundation/Foundation.h> #import “calss.h” 3.程序主要分三个部分:class.h.class.m和main.m,其中:导入系统文件在cl

OC基础(九)description方法

一.基本含义 1.当用%@打印类或对象时候,系统内部默认就会调用 description方法,拿到返回值进行输出,默认输出的是返回类名和对象的内存地址. 其实%@的本质是用于打印字符串. 调用该方法, 该方法会返回一个字符串, 字符串的默认格式 <类的名称: 对象的地址> 2.代码: 1 #import <Foundation/Foundation.h> 2 @interface Animal: NSObject 3 /** 颜色 */ 4 @property (strong, n

普通方法、类的方法、匿名方法 做参数

1.普通方法做参数: 如果方法 是类的方法,那么就不能当函数的参数了,编译会报错,就是说 类的方法的指针 与 普通方法的指针是有区别的,毕竟类的方法的指针 可能包含了 面向对象的 继承 覆盖 等信息: 2.类的方法做参数,就是说类的方法的类型要加上 of object: 3.匿名方法 做参数,要加上 reference to 最终的调试代码: unit Unit6; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils,

IBinder对象在进程间传递的形式(一)

命题 当service经常被远程调用时,我们经常常使用到aidl来定一个接口供service和client来使用,这个事实上就是使用Binder机制的IPC通信.当client bind service成功之后,系统AM会调用回调函数onServiceConnected将service的IBinder传递给client, client再通过调用aidl生成的asInterface()方法获得service的调用接口,此时一个bind过程结束了,我们在client端就能够远程调用service的方

block 做参数

三部分 1,定义函数 /* 传出类定义block */ //定义block typedef void (^ItemClickBlock)(NSInteger selectedIndex); //block 做函数参数 + (instancetype)navigationViewWithItems:( NSArray <NSString *> * )items itemClick:(ItemClickBlock)itemClick; 2,实现 #pragma mark - init block

七.OC基础加强--1.内存管理 2.野指针,内存泄露 3.set方法的内存管理 [email&#160;protected]参数 [email&#160;protected]和循环retain的使用 6.NSString的内存管理

1,内存管理简单介绍 1,为什么要有内存管理? malloc selloc dealloc```需要回头复习 一般的内存 4s 是512m内存:6 是1024m内存: 当内存过大时,会耗尽内存.出现程序闪退. 2.OC内存管理的范围 : 管理任何继承NSObject的对象,对其他的基本数据类型无效. 3.对象类型是程序运行过程中动态分配的,存储在堆区:内存管理主要是对 堆区中的对象的内存管理. 4.OC内存管理的原理 为了防止内存泄露 对象的引用计数器 : 每个OC对象都有自己的引用计数器,是一