标签:
一.面向对象编程OOP(Object Oriented Programming)
1.面向对象语言:C++, Java, C#等
2.两种编程思想
1> 面向过程
特点 : 分析解决问题的步骤,实现函数,依次调用函数
侧重点 : 实现功能
代表语言 : C语言
2> 面向对象
特点 : 分析问题需要参与的对象,各个对象的作用,多个对象协作完成任务
侧重点 : 对象的设计(具有哪些功能)
代表语言 : OC, C++, Java等
二.类和对象
类和对象是面向对象的核心.
1.类 : 具有相同特征和行为的事物的抽象
在Java中,我们用1个.java文件就可以描述清楚一个类;在OC中,一般用2个文件来描述一个类:
1> .h:类的声明文件,用于声明成员变量、方法。类的声明使用关键字@interface和@end。
注意:.h中的方法只是做一个声明,并不对方法进行实现。也就是说,只是说明一下方法名、方法的返回值类型、方法接收的参数类型而已,并不会编写方法内部的代码。
2> .m:类的实现文件,用于实现.h中声明的方法。类的实现使用关键字@implementation和@end。
2.方法
1> 方法的声明和实现,都必须以 + 或者 - 开头
- + 表示类方法(静态方法)
- - 表示对象方法(动态方法)
2> 在.h中声明的所有方法作用域都是public类型,不能更改
2.成员变量
1> @public 全局都可以访问
2> @protected 只能在类内部和子类中访问
3> @private 只能在类内部访问
比Java少了一种作用域:包权限作用域,原因很明显:OC没有包名的概念。
三.用Xcode创建第一个OC的类
1.右击项目文件夹或者文件,选择”New File"
2.选择OS X下的Source中的Cocoa Class
3.输入类名和选择父类
4.创建完毕,项目中就多了两个文件
* 默认情况下,这2个文件的文件名跟类名一致
* 编译器只会编译.m文件,并不会编译.h文件
5.Person.h - 类的声明文件
1> 看第11行,OC中使用关键字@interface来声明一个类,@interface后面紧跟着类名Person。
2> 类名Person后面的冒号":"表示继承,即第11行代码的意思是Person继承自NSObject。
3> 因为NSObject被声明在Foundation.h中,所以在第9行用#import包含了Foundation.h文件。
4> 第13行的@end表示类的声明结束了。@interface和@end是配套使用的。
6.Person.m - 类的实现文件
1> 看第11行,OC中使用关键字@implementation来实现一个类。@implementation后面紧跟的类名,表示究竟要实现哪一个类。
2> 因为Person这个类是声明在Student.h中的,所以在第9行用#import包含了Person.h文件。如果你不包含Person.h,第3行代码肯定报错,因为它根本不知道Person是什么。
3> 第13行的@end表示类的实现结束了。@implementation和@end是配套使用的。
四.添加成员变量和方法
1.在.h文件中声明方法和添加成员变量
正常情况下,我们都是把成员变量定义在头文件中,也就是类的声明文件(.h)中
1> 第13行定义了一个int类型的成员变量age,age的默认作用域是@protected,即可以在Person类内部和子类中访问
2> 成员变量必须写在大括号{ }里面
@public作用域的有:score
@protected作用域的有:age、height
@private作用域的有:weight
3> 第26行声明了age的get方法,方法名就叫做age,OC建议get方法的名字跟成员变量保持一致(如果是在Java中,就应该叫做getAge)
4> 第26行最面的 - 表示这是一个动态方法( + 则表示静态方法)。age前面的(int)表示方法的返回值为int类型,方法的返回值和参数类型都需要用小括号()包住
5> 第29行声明了age的set方法,前面的 - 表示动态方法,(void)表示方法没有返回值
6> 在OC方法中,一个冒号:对应一个参数。由于第29行age的set方法接收一个int类型的参数,参数名为newAge,所以(int)newAge前面有一个冒号:
7> 一定要记住:一个冒号:对应一个参数,而且冒号:也是方法名的一部分。因此第29行set方法的方法名是setAge:,而不是setAge
8> 第32行的方法同时设置age和height,该方法是动态方法,没有返回值.其实andHeight是可以省略的,它只是为了让方法名念起来通顺一点,也让(float)newHeight前面的冒号:不那么孤单
2.在.m文件中实现方法
前面我们定义了一个成员变量age,它的作用域是@protected,外界不能直接访问它。为了保证面向对象数据的封装性,我们可以提供age的get方法和set方法,让外界间接访问age
五.跟Java的比较
如果是在Java中,一个Student.java文件就可以搞定成员变量和方法
六.创建对象
由于OC程序的入口点是main函数,所以在main.m文件中演示Person类的使用。
1.包含Person.h
2.创建对象
1> 在Java中是使用关键字new来创建对象,比如new Student(),其实这句代码做了2件事:
- 给对象分配存储空间
- 调用Student的构造方法进行初始化
2> 在OC中创建对象也需要按顺序做上面所述的2件事
1)调用Person类的静态方法alloc分配存储空间
Person *per = [Person alloc];
- OC是方法调用是用中括号[ ],方法调用者写在括号左侧,方法名写在括号右侧,中间留点空格。因此上面是调用了Person类的静态方法alloc。
- 上面调用的alloc方法会返回分配好内存的Student对象,在等号左边用了一个指向Person类型的指针变量per来接收这个对象,注意per左边的*号。所有OC对象都是用指针变量来接收的,如果你不了解指针,你记住下面这点就行了:利用类名定义一个变量时,类名后面一定要带个*号。
- alloc方法是这样声明的:
可以看到,它的返回值类型是id,这个id代表任何指针类型,你可以暂时理解为:id可以代表任何OC对象,类似于NSObject *。
2)调用Student对象的构造方法init进行初始化
前面调用alloc方法返回的Person对象stu是不能正常使用的,因为仅仅是分配了内存,并没有进行初始化,接下来调用对象的init方法进行初始化
看清楚了,由于init是动态方法,所以这里使用per变量来调用,并不是使用类名来调用。init会返回已经初始化完毕的对象,再次赋值给了per变量。这时候的Person对象per才能正常使用。
3)其实,我们最常见的做法是将alloc和init连起来使用:
Person *per = [[Person alloc] init];
相信有面向对象开发经验的你一眼就能看懂了,在main.m完整代码的第14行。
3.销毁对象
由于OC不支持垃圾回收,因此当不再使用某个对象时,需要调用对象的release方法释放此对象。我们在第9行销毁了stu对象。
这个release方法在这里调用一次即可,不要觉得多调用多几次,对象就会释放地干净一点,这样做会很危险,容易造成野指针错误。
4.其他
1> 也可以调用静态方法new快速创建一个对象
1 Person *per = [Person new];
2
3 [per release];
不过我们还是习惯使用alloc和init来创建对象
2> 前面我们调用了Person的alloc、init、new方法,但是你会发现Person.h中并没有声明这些方法,为什么能够调用呢?原因很简单,这些方法都是父类NSObject的,子类当然可以调用父类的方法。
六.访问公共成员变量和方法
1.第14行创建了Student对象,第26行销毁了对象
2.第17行和第26行访问了Student对象的公共成员变量no,如果不是公共变量,不能像这样直接访问。注意访问方式:对象->成员变量
3.第20行调用了Student对象的setAge:方法,传入参数27修改了成员变量age的值
4.第23行调用了Student对象的setAge:andHeight:方法,同时修改了成员变量age和height的值
5.第29行调用了Student对象的age方法获取成员变量age的值
6.第32行输出了age和no的值,输出结果:
对象 : 对象是类的实例, 类是对象的类型. 万事万物皆对象
开发中 : 先定义类, 再创建对象, 然后使用对象.
定义类包含两部分 :
接口部分 : 对外声明类的实例变量(特征)和方法(行为), 接口的标志 @interface…@end
实现部分 : 实现类的方法(行为), 标志 @implementation…@end
02-类和对象
标签:
原文地址:http://www.cnblogs.com/lile2015/p/4967645.html