热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ObjectiveC复合(Compostion)——存取方法

0x01存取方法是间接的一个例子上一篇中,我们已经构造了一台“车”。假设现在我想要随时更换自己喜欢的发动机和轮胎,就要用到“存取方法”。“存取方法

0x01 存取方法是间接的一个例子

上一篇中,我们已经构造了一台“车”。

假设现在我想要随时更换自己喜欢的发动机和轮胎,就要用到“存取方法”。

“存取方法”是用来读取或改变某个对象属性的方法,例如此前见过的setFillColor:就是一个存取方法。

如果我们要对其他对象中的属性进行操作,应该尽量使用对象提供的存取方法,绝对不要直接改变对象里面的值,而应该使用setter方法进行更改。

正确使用“存取方法”将会使程序更加灵活。



0x02 方法的命名规则

1、虽然说方法的命名是自由的,但为了程序的可读性,我们还是应该遵循Cocoa的惯例:

setter方法应根据它所要更改的属性名称来命名,如“set+属性名”;

getter方法只需以其返回的属性名命名即可,即“属性名”。

因为get这个词在Cocoa中有特殊含义,如果get出现在Cocoa的方法名称中,就意味着这个方法会将传递给它的参数作为指针来返回数值。


2、setter方法和getter方法一般是成对出现的,当然也可以不成对出现。如对于只读特性只有getter方法,对于密码特性只有setter方法。



0x03 存取方法的实现


我们先在Car的接口中对添加的setter和getter方法进行声明:

@interface Car : NSObject
{Engine *engine;Tire *tires[4];
}//New Code
- (Engine *) engine;
- (void) setEngine: (Engine *) newEngine;
- (Tire *) tireAtIndex: (int) index;
- (void) setTire: (Tire *) tire atIndex: (int) index;
//New Code- (void) print;
@end // Car


第一对存取方法是为了访问发动机的属性:

- (Engine *) engine;
- (void) setEngine: (Engine *) newEngine;

调用Car对象的engine方法可以访问engine变量,调用setEngine:方法可以更改发动机属性。

下面是这两个方法的实现:

- (Engine *) engine
{return (engine);
} // engine
- (void) setEngine: (Engine *) newEngine
{engine = newEngine;
} // setEngine

我们看到getter方法engine返回的是一个指针,指向Car中的Engine对象。实际上是返回实例变量engine的当前值;

同样的,setter方法setEngine:将newEngine的值赋给engine实例变量。实际上被修改的是engine的指针值。

在Objective-C中所有对象间的交互都是通过指针实现的!


第二对存取方法是为了访问轮胎的属性:

- (void) setTire: (Tire *) tire atIndex: (int) index;
- (Tire *) tireAtIndex: (int) index;


由于汽车的4个轮胎处于4个位置,所以Car对象中必须包含一个表示轮胎位置的数组:

- (void) setTire: (Tire *) tire atIndex: (int) index{if (index <0 || index > 3) {NSLog (@"bad index (%d) in setTire:atIndex:",index);exit (1);
}tires[index] = tire;
} // setTire:atIndex:
- (Tire *) tireAtIndex: (int) index
{if (index <0 || index > 3) {NSLog (@"bad index (%d) in "tireAtIndex:", index);exit (1);
}return (tires[index]);
} // tireAtIndex:

因为tire是一个C风格的数组,对于其索引值是否有效,编译器是可能直接忽略的。所以我们自己得用if条件语句来判断index值是否合理,这是一种防御式编程思想

setTire:方法的声明格式看起来不太一样,这是因为它拥有两个参数,往后学习会更加理解这种写法。


最后修改main()函数:

int main (int argc, const char * argv[]) {Car *car = [Car new];//事实上可以在Car类中把init方法删掉,因为下面的代码已经做了init方法的工作Engine *engine = [Engine new];[car setEngine: engine];for (int i = 0; i <4; i++) {Tire *tire = [Tire new];[car setTire: tire atIndex: i];}[car print];return (0);
} // main

程序运行结果没有变化,但我们改进了它的内部结构,使程序更加灵活:

I am an engine. Vrooom!
I am a tire. I last a while.
I am a tire. I last a while.
I am a tire. I last a while.
I am a tire. I last a while.



0x04 存取方法的应用

我们已经为Car类添加了存取方法,那换配置就是随心所欲的事了。

现在来为这台车换一个发动机:

@interface Slant6 : Engine
@end // Slant6@implementation Slant6
- (NSString *) description
{return (@"I am a slant- 6. VROOOM!");
} // description
@end // Slant6

创建这台Slant6发动机,继承了Engine超类的属性。但是重写了description方法,输出了新发动机的信息。


接着我们换轮胎:

@interface AllWeatherRadial : Tire
@end // AllWeatherRadial@implementation AllWeatherRadial
- (NSString *) description
{return (@"I am a tire for rain or shine.");
} // description
@end // AllWeatherRadial


最后修改main()函数,这台车使用了全新的发动机和轮胎:

int main (int argc, const char * argv[]) {Car *car = [Car new];for (int i = 0; i <4; i++)
{//New CodeTire *tire = [AllWeatherRadial new];//New Code[car setTire: tire atIndex: i];}//New CodeEngine *engine = [Slant6 new];//New Code[car setEngine: engine];[car print];return (0);
} // main

运行程序后,可以发现输出已经更新为新配置了:

I am a slant- 6. VROOOM!
I am a tire for rain or shine.
I am a tire for rain or shine.
I am a tire for rain or shine.
I am a tire for rain or shine.





推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
author-avatar
小小伟
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有