iOS成长之路基础篇 – (2) 认识 Objective-C 的类
上一篇中我总结了OC的基本语法中从C语言扩充来的知识,在这一篇中,我将总结OC的基本语法的使用。如何开发一个OC对象?
预备知识
首先,我想介绍一下在Mac OS X下面如何通过命令行编译链接OC文件:
第一个是编译:cc -c 源文件.m
接着链接:cc 源文件.o -framework Foundation
最后执行:./a.out
为什么后面跟着一个-framework Foundation?这是因为你是用到了一个框架Foundation,如果以后在开发中使用到了系统的框架,都可以这样引入,否则不能通过链接。
为什么这里是a.out?因为在类Unix系统中,我们经过命令行编译链接通过后的可执行文件如果没有指定文件名,默认是a.out。
如果你不想看到链接的过程可以直接编译链接一步到位:cc 源文件.m -framework Foundation
接着介绍一个类:字符串类NSString
char *ss = "xxxx"; //c语言字符串
NSString *str = @"xxxxx"; //oc字符串
NSString *newStr = [NSString stringWithFormat:"My name is %@", str];
[str length]; //获得字符串的长度,返回的是无符号int
Objective-C语法
在上一篇中我已经对比了C和OC语言,说过C语言是面向过程的一种语言,而OC是面向对象的一种语言。那么下面我将总结OC语言的核心开发知识——class(类)。
首先,在一个类中,有各类东西,一类叫做成员变量(也称属性),一类叫做成员方法(也称行为)。
- 成员变量(属性)
成员变量有四种作用域:
- @private 只能在当前类访问
- @package介于@private和@public之间,同一框架
- [@protected<====>默认缺省] 只能在当前类和子类中访问
- @public任何地方访问
注意:
@interface中的成员变量默认protected
@implementation中的成员变量是private
OC的成员变量:
成员变量:默认为 protected(一般也就选择的是默认)
成员变量命名:_xxx(也就是成员变量命名以下划线开头)
OC的成员变量一般都要定义getter,setter 方法,一般的命名 setAge:set方法 age:get方法
//People.h文件
#import <Foundation/Foundation.h>
@interface People: NSObject
{
int _age;
}
- (int)setAge;
- (void)setAge:(int)age;
@end
//People.m文件
#import "People.h"
@implementation People : NSObject
- (int) age
{
return _age;
}
- (void)setAge:(int)age
{
_age = age;
}
@end
- 成员方法(行为)
说完成员变量,我们就要说说成员方法了。在一个类中一般将方法分为两类:一类是对象方法,一类是类方法。在上一篇我们同样说过,对象方法以 “-” 标记,类方法使用 “+” 标记。
和成员变量是一样,方法需要声明,方法的声明在头文件中和属性的getter,setter方法在一块。实现在源代码文件中实现,和getter,setter方法的位置也一致。
注意:
对象方法可以调用类方法,反过来不能调用,如果想调用,必须实例化一个对象。
- 弱语法
OC语言中有一个弱语法现象,OC是运行时才检测有没有实现相应的方法,编译过程只给出警告:可能找不到对应的方法。在这里需要注意,在一个类中可以没有interface 或者 函数声明。 但是必须要有实现implementation(实现)。
//下面也可以完成类的定义
@implementation People : NSObject
{
//成员变量
}
//实现方法
@end
- self
self是OC语法中的一个关键字,其实质含义是变化的,指的是当前的调用者,谁调用指的就是谁,比如对象调用了,就是对象,子对象调用就是子对象,类调用了,就是指这个类。
self->_age //指向方法的调用者
[self xxx] //调用方法(类方法和对象方法都可以)
- 继承
继承是面向对象的三大特性之一,所以OC也是有继承的,OC和C++不一样,OC是单继承。一般A类继承了B类,我们称A类为子类,B类为父类(或超类)。super关键字:指向父类,其中,super指向的方法取决于调用者是类还是对象。
在OC继承中,如果父类和子类在一个文件中,父类的声明必须放在子类声明之前,同时,子类中的成员变量不能和父类中的同名。
同时有继承,有分类(Category)时(后面讲),方法查找的顺序: 分类Category—>子类subclass—>父类superclass
- 多态
没有继承就没有多态,父类指针指向子类对象,称之为多态。
多态中父类中需要有方法声明,否则会有编译警告。
多态的局限:父类类型的指针不能调用子类的特有方法,需要强制转换。
- OC中的点语法
OC中的点语法是Xcode的高级功能,它将点语法会自动转换成getter,setter方法。这是Apple为了从其他语言,比如Java转过来的开发者而设计的。
p.age = 10; //与[p setAge:10]等价
int age = p.age; //与int age = [p age]等价
- 其他
- 在OC中,如果A对象中有一个成员变量是B对象,那么A对象中的B对象要先进行设置,否则不能设置B对象中的成员,那样是没有意义的。
- 类名的使用:后面需要跟 * 号,除了需要使用类方法时类名后面不需要加 * 号,再就是其他Apple官方文档中定义的一些关键字,其中已经包含了*的不需要。
- xcode特有的注释(预编译指令):
#pragma mark
注释语言可以注释代码组#pragma mark -
注释语言注释代码组的同时使用横线将代码分隔开来
- @property和@synthesize关键字
上面我们在OC中定义成员变量的时候需要同时完成getter,setter方法,以上面的代码书写,是没有任何意义的垃圾代码。为了提高开发人员的开发效率,Apple为Xcode增加了一些功能,这使得OC多出一些关键字,现在要说的就是为了简化getter,setter方法的关键字。@property关键字:写在@interface中,@synthesize关键字:写在@implementation中。他们的作用:
- 如果没有成员变量,自动生成;如果有,使用自己的。
- 如果没有getter或者setter,自动生成;如果有,使用自己的。
- 同时实现了getter和setter时,@property将不会做任何事情。
//写在@interface中
//getter和setter声明。一般情况下分开写每一个成员变量
@property int age, height;
//写在@implementation中
//getter和setter实现,一般情况下分开写每一个成员变量
@synthesize age = _age, height = _height;
注意:
Xcode4.4以后,可以不用显式声明成员变量。@property带有@synthesize的实现,此时的成员变量为private。
- 总结
这一篇,我主要总结OC中类的关键的基本知识点,当然可能有一些地方还没有注意到,后面会继续补充,下一篇总结类的加载机制和一些其他内容。