Objective-C官网学习笔记(一)—— Defining Classes
Defining Classes
当你为OS X 或 iOS编写程序的时候,大多数时候你都在忙着编写对象。Objects对于Objective-C就像对象对于其他面向对象的编程语言,他们将数据与相关行为打包。
一个应用程序被构建为一个由相互关联的对象组成的生态系统,对象相互沟通解决具体的问题,像展示可视化界面,响应用户输入或存储信息。对于OS X或iOS开发,你不需要从零开始创建对象来解决所有的问题。相反,有一个庞大的现有对象库可供使用,由Cocoa(for OS X)和Cocoa Touch(for iOS)提供
其中一些对象可以立刻使用,像一些基本的数据类型如string和number,或一些用户界面元素如按钮或者表格。一些是设计好的,可以用你自定义的代码实现的,按照你需要的方式运行的。应用程序开发过程涉及决定如何最好地自定义底层框架提供的对象并将其与您自己的对象相结合,从而为您的应用程序提供独特的特性和功能集。
在面向对象的编程术语中,一个对象是一个类的实例。该章节将演示如何通过声明一个接口来在OC中创建类,该接口描述了你打算如何使用该类及其实例。这个接口包括了类可以接受的消息列表,因此你还需要提供类的实现,其中包含为响应每条消息而执行的代码
Classes Are Blue prints for Objects
一个类描述对于任何特定类型的对象都通用的行为和属性。对于string对象(在OC中,这是一个NSString类的实例),它的类提供各种各样的方法来检查和转换它所包含的字符。相同的,用于描述number的对象的类(NSNumber)也提供围绕内部数值的功能,像将值转换为不同类型的函数。
同样的,根据同一蓝图建造的多栋建筑在结构上完全相同,每一个类的实例与其他所有相同类的实例共享一样的属性和方法。每个NSString实例的表现形式都相同,不管它包含的内部字符串是什么样的。
任何特定对象都旨在以特定方式使用。你可能知道一个字符串对象代表一些字符串,但是你不需要知道用于存储这些字符的确切内部机制。你不需要知道对象本身用来直接处理它的角色的内部行为,但是你需要知道你应该如何与该对象交互,例如向它询问特定字符或请求一个新对象,或将其中所有原始字符都转换为大写。
在Objective-C中,类接口准确地制定了给定类型的对象将如何被其他对象使用。换句话说,它定义了类实例与外界之间的公共接口。
Mutability Determines Whether a Represented Value Can Be Changed
一些类定义对象是不可变的。这意味着对象包含的值必须在对象创建的时候初始化,并且随后不能被其他对象更改。
在Objective-C中,所有的基本对象NSString和NSNumber时不可改变的。如果你想表示一个新的数字,你必须使用一个新的NSNumber实例。
一些不可变类同样提供可变的版本。如果你特别需要在运行时改变字符串的内容,例如添加字符到通过网络收到的字符串,你可以使用NSMutableString类的实例。这个类的实例表现就跟NSString对象一样,除了它们还提供更改对象所代表的字符的功能。
虽然NSString和NSMutableString是不同的类,但是它们有很多相同点。与其从头编写两个恰好具有相似行为的安全独立的类,不如利用继承
Classes Inherit from Other Classes
在自然界中,分类学使用物种、属和科等术语将动物分类。这些组是等级制的,因此多个物种可能属于一个属,多个属可能属于一个科。
在面向对象编程的世界里,对象也被分成不同的层次。对象不是用不同的术语来表示不同的层次,不如属或者种,而是简单地组织成类。就像人类作为人科成员继承某些特征一样,可以将类设置为从父类继承功能。
当一个类从其他类继承的时候,子类将继承父类定义的所有行为和属性。它也可以定义自己的附加行为和财产,或者覆盖父级的行为。
在Objective-C字符串类的情况下,NSMutableString的类描述指定了该类继承自NSString类
所有NSString提供的方法NSMutableString都可以使用,例如查询特定字符或返回字符串的大写。但是NSMutableString也添加了一些自己的方法使你可以增加、插入、替换或删除子字符串和单个字符。
The Root Class Provides Base Functionality
就像所有生物都具有一些基本的生命特征一样,某些功能在Objective-C的对象中都是通用的。
当Objective-C对象需要与另一个类的实例一起工作时,期望另一个类提供某些特征和行为。
出于这样的原因,Objective-C 定义了一个根类,绝大多数其他类都继承自根类,称为NSObject。当一个对象遇到另一个对象时,它希望至少能够使用NSObject类描述定义的基本行为进行交互。
当你定义自己的类时,你需要至少继承NSObject。一般来说,你应该找到一个Cocoa或Cocoa Touch对象,他提供最接近你需要的功能并从中继承。
例如,如果你想在你的iOS app中定义使用一个用户按钮,并且提供的UIButton类没能提供足够的可定制属性来满足你的需求,创建一个继承自UIButton的新类比继承NSObject更有意义
如果你只是简单的继承自NSObject,你需要复制 UIButton 类定义的所有复杂的视觉交互和通信,只是为了让您的按钮以用户期望的方式运行。此外,通过从UIButton继承,你的子类会自动获得可能应用于内部UIButton行为的任何未来增强功能或错误修复
UIButton类它自己也是由UIControl继承的,UIControl描述了iOS上所有用户界面空间共有的基本行为。UIControl类又继承自UIView,赋予它与屏幕上显示的对象相同的功能。UIView继承自UIResponder,允许它响应用户输入,例如点击,收拾和抖动。最终,在这棵继承树的根部,UIResponder继承自NSObject
这种继承链意味着UIButton的任何自定义子类不仅会继承UIButton本身声明的功能,还有从每个超类依次继承的功能。你最终会得到一个行为像按钮的对象的类,可以在屏幕上展示,响应用户输入,并且可以跟任何Coco Touch基础类沟通。
对于需要使用的任何类,为了清楚它到底能做什么,请务必牢记它的继承链。例如,为Cocoa和Cocoa Touch提供的类参考文档允许从任何类轻松导航到它的每个超类。如果你无法在一个类接口或参考种找到你要查找的内容,那么很可能在链上游的超类中定义或记录了它。
The Interface for a Class Defines Expected Interactions
面向对象编程的众多好处之一就是前面提到的思想——为了使用一个类,你需要知道的就是如何与其实例交互。更具体的说,一个对象应该被设计成隐藏其内部实现的细节。
如果你在一个iOS APP中使用标准的UIButton,你无需担心如何操作像素使按钮出现在屏幕上。你所需要知道的事你可以修改一些核心属性,像按钮的标题和颜色,并且相信当你把它们添加到你的可视化界面上时,它们会被正确的展示并且表现的像你期望的一样。
当你定义自己的类时,你需要从弄清楚这些公共属性和行为开始。你希望公开访问哪些属性?是否允许更改这些属性?其他对象如何与你的类的实例通信。
这些信息在类的interface部分定义,表明了你希望其他对象与你类实例交互的方式。公共接口与构成类实现的类的内部行为分开描述。在Objective-C中,接口和实现通常放在单独的文件中,因此你只需要将接口公开即可。
基本语法
Objective-C用于定义接口的基本语法如下
1 |
|
这个例子定义了一个名叫SimpleClass的类,继承自NSObject。
公共属性和行为在@interface声明中。在这个例子中,除了超类之外没有指定任何东西,所以在SimpleClass实例上预期可用的唯一功能就是从NSObject继承的功能。
属性控制对对象值的访问
对象通常具有供公共访问的属性。如果你想定义一个类来记录使用APP的人,例如,你可能觉得你需要字符串类型的属性来记录人的名和姓。这些属性的声明应该添加到接口中,如下所示
1 |
|