《Objective-C入门经典》——2.2节使用对象创建C

简介:

本节书摘来自异步社区《Objective-C入门经典》一书中的第2章,第2.2节使用对象创建C,作者【美】Jesse Feiler,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.2 使用对象创建C
Objective-C入门经典
Objective-C是从C的基础上演化而来的,Brian W. Kernighan和Dennis M. Ritchie在他们撰写的经典书籍《C程序设计语言》的引言中,将C语言描述成“UNIX操作系统的语言”。C本身是一门相对比较简洁的语言(该书的第一版称之为“表达式经济”),但在20世纪80年代,C在面向对象语言的开发中担当着一个关键角色:C++和Objective-C都是以C程序开始并将其原生语法转换成兼容的C代码的。C++在很大程度上是受到了Simula的影响,而Objective-C则主要受到了Smalltalk的影响。在过去几年中,人们对这两门从C语言演化而来的面向对象语言所带来的价值展开了激烈的争论。

时下,Objective-C语言可能是作为Mac OS X和iOS平台的语言而为人们所熟知的,因此将其与其他语言进行比较并没有太大的意义。读者如果需要复习一下C的基本语法,可以参考附录A。

下面进入Objective-C的世界。与自然语言一样,如果一开始身处自己所熟悉的语言世界,接着进入另一门全新的语言世界中,那么人们将会需要花费较长的时间来学习新语言。当然,计算机语言的普遍原理仍然适用于Objective-C,同时面向对象程序设计的基本原则也适用于Objective-C。对于大多数人来讲,Objective-C语言与其他诸如C或C++之类的语言之间的最大的差别是Objective-C的语法看上去有很大的不同,下一节将会介绍这一差别的核心:方法和消息。

记住:不要翻译下面几节中介绍的概念和语法。像教授自然语言的老师所讲的那样,沉浸下去,开始编写Objective-C程序。

2.2.1 理解数据抽象
数据抽象是Objective-C语言的关键原则之一。抽象不仅仅是一个计算机术语,它还被广泛地应用于其他领域。它是一个通盘考虑一组概念或对象、剔除它们之间的差别并保留它们之间共同的抽象部分的过程,这有点像是一个逻辑或哲学方面的练习,或者像是小孩子们之间诸如“这些东西之间有什么共同点”之类的游戏。如果待比较的东西是猴子、金鱼以及人,那么答案可能是它们都是动物。这就是对那些对象的一种抽象。

抽象的一个关键点是隐藏与抽象无关的细节,这样抽象出来的信息的可辨认性就会更强。数据抽象的这一特点在Objective-C中是非常关键的。在语言、语言的使用以及语言用法的最佳实践中,隐藏对象的细节信息能够增强抽象的可用性。隐藏在Objective-C中也是至关重要的。

在创建了隐藏差异的抽象对象之后就可以编写操作这些对象的代码了。在隐藏了差异之后,在编写代码时就可以放心地忽略这些差异了。隐藏抽象对象之间的差异是一条非常重要的原则,读者必须要学会并谨记这条原则。很多人是从找出哪些差异应该被隐藏开始学习Objective-C语言的(以及其他语言,本书关注的是Objective-C)。

现在假设需要创建一个银行账号类,那么对于外部世界来说,不管这个账号是一个存款账号还是一个支票账号,它的外观和行为方式应该是一样的。这个类可能会报告其当前余额和其当前未完成的业务,其子类可能会报告存款或支票账号专有的属性,而这些操作可能无法由抽象的银行账号类来完成,因为像报告还没有取现的支票这类操作是存款账号无法完成的(除非这是一个混合账号,用户可以根据存款账号开出支票)。

2.2.2 研究封装
封装是与数据抽象相关联的,程序清单2.1通过一段表示银行账号的伪代码对封装的概念进行了阐述(尽管这仅仅是一段伪代码,但这段代码展示了一些Objective-C语法,本书的第2部分将对此进行详细介绍)。

程序清单2.1 BankAccount类的伪代码


54d581ada329b4ddcffcc9328647e25e0998e6bb

这是银行账号类的一个方法,该方法返回账号的余额。在调用时需要传入账号类型,不同的账号类型会触发不同的例程来返回相应的值。

上面这段代码通过分解代码块展示了封装的原则。银行账号类对每种账号的特性进行了抽象。在调用这个方法时可以传入各种类型的账号,因此读者可能会觉得这已经抽象出了类数据。

数据抽象中封装的概念认为抽象对象本身应该能够自给自足,即如果拥有一个银行账号类的实例,那么就应该能够在不传入任何其他信息的情况下获取其余额,自包含(封装)的类能够完成任何力所能及的事情。

这种方式意味着需要在银行账号类中存储账号类型。

程序清单2.2给出了银行账号类头文件的伪代码。

程序清单2.2 BankAccount头文件


fd9cfa1744e857282c52111fa1152cc3817a863e

由于账号类型是存储在对象里面的,因此返回银行账号余额的方法已经拥有该项信息了,这样就可以修改程序清单2.1中的代码使其使用这个内部值了,如程序清单2.3所示。

程序清单2.3 根据内部账号类型变量值返回银行账号余额


4e5c40798b1b71f04c865280cf346d75fd8e4e9f

从程序清单2.2给出了类的头文件就可以看出账号类型变量被声明成private了,这意味着只有在该类内部才能访问这个变量。在这个类中对外部世界可见的部分只有那个返回余额的方法,该方法根据对象内部的数据(账号类型,或许还有交易数据)来返回相应的余额。这个银行账号类既是抽象的,同时也是经过封装的,因为从外部世界来看,该类所能做的工作就是根据其内部状态返回余额,任何访问该类的人都不需要知道这个类是如何完成这件事情的。

注意,从程序清单2.3中可以看出,这个类的所有内部工作细节都被隐藏起来了,各种不同类型的银行账号的类型值并没有被暴露出来。这种结构对于保护自己的代码免受外部变更的干扰是非常有用的。当创建一个银行账号的实例时可以通过传入一个参数来设置其账号类型,这个参数可能是一个诸如“超级存款账号”之类的字符串。当一个具体的银行账号实例被创建出来之后就需要将这个字符串翻译成账号的内部类型(这通常是由银行的市场部门控制的),在这之后市场部门所定义的账号术语就与银行账号的内部功能无任何关系了。同样,在改变一种账号类型的功能时无须改变暴露给外部世界的任何信息(在银行业务中,当不同银行系统的校准规则不同时就会发生这种情况,即要强制使用新的计算方式)。

阅读第8章以获取更多有关设置实例变量的作用域方面的知识,如将变量声明成private、public或protected。

2.2.3 使用访问器(Accessor)管理封装
管理封装的一个重要工具是使用访问器,访问器是一组允许在不直接引用对象的实例变量的情况下就能够访问实例变量的小型方法。访问器有时候仅仅是完成设置和提取一个变量的值的工作,但它们也可能会执行一些转换和修改工作。例如在Core Data框架中有很多框架访问器方法会在Core Data栈基本元素不存在的情况下创建一个基本元素。在创建了这个基本元素之后,对象就能够在下次被请求该元素时快速返回该元素了。

相关文章
|
iOS开发 开发工具 git
《Objective-C入门经典》——导读
本节书摘来自异步社区《Objective-C入门经典》一书中的目录,作者【美】Jesse Feiler,更多章节内容可以访问云栖社区“异步社区”公众号查看
1124 0