一、类
1、什么是类方法
首先我们通过一个例子来看看 对象方法 和 类方法有什么区别
分别用 对象方法 和类方法来 实现计算器的+、-、*、/
首先用 对象方法:
程序如下:
Calculator声明部分
Calculator实现部分
主函数部分
打印输出
下面用 类方法来实现 计算器功能+、-、*、/
程序代码如下
类声明代码
类实现代码
主函数代码
打印如下
总结:
通过对同一个例子用 对象方法 和 类方法类 来对比实现会发现两者有不同之处:
1>第一就是两种方法的格式不同 类方法是+号开头、对象方法是 - 号开头
2>在类的声明中 类方法没有实例变量
3>在main函数中,调用类方法是不需要在使用[类名 new]申请空间,而是直接调用
在 对象调用时还需要定义一个 “对象”
2、类方法概述及定义方法
Objective-C中的类可以声明两种类型的 方法对象(实例)方法 和 类方法
1)类方法概述
对象方法就是一个方法,它在类的一个具体实例的范围内执行。也就是说,在你调用一个实例方法前,你必须首先创建类的实例。
而类方法,比较起来,也就是说,不需要你创建一个实例。
+:表示类方法,就是类调用方法,不依赖与任何对象的方法
- :表示是实例(对象)方法,只能是对象可调用,依赖与任何对象的方法
2)类方法的调用格式
[类名 类方法名称];
3)对比 对象方法调用 和 类方法调用
对象方法:
Dog类
对象方法声明:-(void)run;
调用run方法
定义一个对象:Dog *dog=[Dog new];
用对象来调用方法: [dog run];
类方法:
Dog类
类方法声明:+(void)run;
调用run 方法:
用类来调用类方法:[Dog run];
3、下面我们从内存存储的角度来分析 对象方法 和类方法
我们用上面的计算+、-、*、/ 的例子来说明:
当我们声明和实现 Calculator类并且定义一个对象calculator后的内存情况为:
当我们给 对象实例变量赋值后,内存存储为:
当我们要开始用对象 calculator来调用方法 add时:
因为对象calculator存储的是新申请来的地址,所以会从地址中找到内存堆中的_isa地址并且通过_isa地址找到内存代码区,然后在代码区中寻找要调用的方法。
当我们创建一个LeiCalculator类并且实现时,内存中的情况如下:
当我们开始调用的时候 [LeiCalculator add:10 addNum:3];时,内存存储情况
类方法在调用时会直接去调用方法,并且把实参数值传给形参
总结:
类方法调用最大的优点就是占用内存小。
4、类方法的调用及注意事项
1)类方法可以和对象方法同名,这个并不影响使用,对象方法由实例对象访问调用,类方法要通过类直接访问调用,不会有交叉相互影响
2)类方法也可以是从父类继承而来,子类可以重新写类方法,如description类方法就可以在子类里重新定义这个方法。
3)类方法和对象方法一样在@interface里声明,在@implementation里实现
4)类方法只能被向类发送类方法消息才被执行,向实例对象发送类方法是不能被触发执行的。
5)在类方法里使用了self,这个self执行的类对象class object而不是实例对象instance object
5、类方法易犯的错误
1)类方法的优点
>节省内存空间
>提高了效率
>作为工具方法
2)类方法的易犯错误
在类方法中使用了类的成员变量
注意:
在类方法中不能使用类的成员变量
在对象方法中可以使用类的成员变量
6、类方法与对象方法比较
1)对象方法:
1.>以 - 号开头
2.>可以使用成员变量
3.>对象方法可以调用当前对象或者其他对象的方法(是通过将对象作为参赛传入方法)
2)类方法:
1.>以+开头
2.>不可以使用成员变量
3.>用类名调用类方法
4.>类方法可以调用对象方法(是通过将对象作为参数传入方法)和类方法
5.>类方法不可以调用自身,会造成死循环
总结:
如果我们调用一个方法,该方法中不需要使用成员变量,那么我们可以将该方法声明为类方法
例如:
有一个手机类iPhone,该类中有一个枚举类型的实例变量_color
要求:实现返回手机颜色名,而非枚举值
类声明部分
类实现部分
对象方法
类方法实现
主函数部分
打印输出
二、封装
1、为什么要进行封装
不封装的缺点:
当一个类把自己的属性暴露给外部的时候,那么该类就失去对属性的管理权
将数据隐藏起来,只能用此类的方法函数才可以访问或者设置数据,不可被外部任意存储是面向对象设计本质。降低了数据被无用的可能性!
在OC语言中,使用@interface 和 @implementation来处理类
@interface就好像暴露在外面的时钟表面,像外界展示以及接口。
@implementation就好像隐藏在时钟内部的构造实现,把具体的实现封装了起来
实例变量默认只能被当前类的对象方法访问
2、封装的实现步奏
定义设置实例变量(setter)和访问实例变量(getter)的方法
1)setter方法(设置器)
在开发过程中,考虑到安全性要求我们一般不在成员变量名前面使用@public、@protected等关键字修饰,而是使用set方法来为对象提供成员变量的值。在set方法的内部也可以对一些不合理的赋值进行筛选过滤。
set方法的作用:为外界提供一个设置成员变量值的方法
2)set方法的书写规范:
1.>set方法一定是一个对象方法
2.>set方法一定不能有返回值
3.>set方法必须以 set 开头
4.>set之后跟的是 实例变量去掉下划线,并且首字母大写
5.>set方法一定有参数,而且参数的类型和实例变量的类型一致
6.>set方法的形参名:一般是 去掉下划线的实例变量名
7.>形参名不能和 实例变量名同名
8.>set方法实现中,就是用形参给实例变量赋值
3)set方法的好处:
不让数据暴露在外,保证了数据的安全性
对设置的数据进行过滤
4)getter方法(访问器)
get方法的作用:为调用者返回对象内部的成员变量
5)get方法书写规范
1.> get方法一定是一个 对象方法
2.> get方法一定有返回值,返回值的类型 和实例变量的类型要一致
3.> get方法的方法名 是去掉下划线的实例变量名
4.> get方法一定没有参数
5.> get方法的实现中,一定是返回值实例变量值
下面通过实例来感受下 set方法、get方法
实例程序如下
类声明部分
方法实现部分
主函数部分
打印输出