------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
------封装-------
1.什么是封装:
封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
2.封装的好处:
将变化隔离。(不管里面怎么变,使用者不需要知道)
便于使用。(使用者只需按照一定的方法使用就可以了)
提高重用性。(任何人都可以对已封装好的功能进行操作)
提高安全性。(由于暴露给使用者的只是一些外在的操作环节,而不是里面本质的东西,所以就提高了对他的维护性,也就是安全性)
3.封装的原则:
将不需要对外提供的内容都隐藏起来。
把属性都隐藏,提供公共方法对其访问。
set方法作用:给外界提供一个设置成员变量值的方法,可以在方法里面对参数进行相应过滤
get方法作用:为调用者返回对象内部的成员变量
main.n #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [Person new]; //设置名称 [p setName:@"萨达姆"]; [p setAge:52]; [p setSex:kSexYao]; [p setHeight:2.12f]; NSLog(@"%@,%d,%d,%.2f",[p name],[p age],[p sex],[p height]); } return 0; } Person.h #import <Foundation/Foundation.h> typedef enum {kSexMan,kSexWomen,kSexYao} Sex; @interface Person : NSObject { //姓名 NSString *_name; //年龄 int _age; //性别 Sex _sex; //身高 float _height; } //给每一个实例变量定义两个方法:设置变量的方法(set) 获取变量值得方法(get) //set方法的书写规范: //1) set方法一定是一个对象方法 //2) set方法一定不能有返回值 //3) set方法必须以set开头 //4) set之后跟的是 实例变量去掉下划线,并且首字母大写 //5)set方法一定有参数,而且参数的类型和实例变量的类型一致 //6) set方法的形参名 一般是 去掉下环线的实例变量名 //7)形参名不能和 实例变量名同名 //8) set方法实现中,一定要用形参给实例变量赋值 //_name的set方法 -(void)setName:(NSString *)name; //int _age; -(void)setAge:(int)age; //Sex _sex; -(void)setSex:(Sex)sex; //float _height -(void)setHeight:(float)height; //get方法书写规范 //1) get方法一定是一个对象方法 //2) get方法一定有返回值,返回值的类型和实例变量的类型要一致 //3) get方法的方法名 是去掉下环线的实例变量名 //4) get方法一定没有参数 //5) get方法的实现中,一定是返回实例变量值 //NSString *_name; //以后获取name的值,都统一的使用name的get方法 -(NSString *)name; //int _age; -(int)age; //Sex _sex; -(Sex)sex; //float _height -(float)height; @end Person.m #import "Person.h" @implementation Person //**************** set 方法的实现 ********* //_name的set方法,以后对_name设置值,一律使用此方法 -(void)setName:(NSString *)name{ //给实例变量赋值 _name = name; } //int _age; -(void)setAge:(int)age{ _age = age; } //Sex _sex; -(void)setSex:(Sex)sex{ _sex = sex; } //float _height -(void)setHeight:(float)height{ _height = height; } //**************** get 方法实现 ************ -(NSString *)name{ return _name; } //int _age; -(int)age{ return _age; } //Sex _sex; -(Sex)sex{ return _sex; } //float _height -(float)height{ return _height; } @end
---------------继承--------------
三.继承和派生:
继承格式:
@interface Cat : Animal
@end
继承定义: 子类拥有了父类属性和方法.
派生: 父类向下产生子类的过程称为派生
派生类不但包含了基类的方法和属性,同事派生类还可以增加自己的方法和属性
继承的注意事项:
1. 子类不能定义和父类同名的成员变量,但是可以继承父类的成员变量
2.子类可以重写父类的方法。
3.调用某个方法时,优先去当前类中找,如果找不到,去父类中找;
3. OC类支持单一继承,不支持多继承
狗继承动物
Animal.h #import <Foundation/Foundation.h> @interface Animal : NSObject -(void)eat; -(void)bark; @end Animal.m #import "Animal.h" @implementation Animal -(void)eat{ NSLog(@"动物会吃"); } -(void)bark{ NSLog(@"动物会叫"); } Dog.h #import "Animal.h" @interface Dog : Animal -(void)eat; @end Dog.m #import "Dog.h" @implementation Dog //把父类的方法,在子类中重新给实现了 //这种做法就称之为:方法的重写 -(void)eat{ NSLog(@"狗会吃"); } -(void)bark{ NSLog(@"狗会叫"); } @end main.m #import <Foundation/Foundation.h> #import "Animal.h" #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { //先查找当前类有没有eat和 bark, //如果有,先调用自己的 //如果没有,查看父类有没有bark方法 // 如果父类还没有 去爷爷类 // 如果有,就执行 Dog *d = [Dog new]; [d eat]; [d bark]; //ani 调用它自己的吃和叫得方法 Animal *ani = [Animal new]; [ani eat]; [ani bark]; } return 0; }
方法的重写:父类的方法在子类中重新给实现了
super 的作用
1.直接调用父类中的某个方法
2.super 处在对象方法中,那么就会调用父类的对象方法
super 处在累方法中,那么就会调用父类的类方法
3。使用场合:子类想重写父类的一些方法时想保留一些父类的行为
继承的好处:
不改变原来模型的基础上,拓充方法
建立了类与类之间的联系
抽取了公共代码
坏处:耦合性强
继承的使用场合:
1.当两个类拥有相同的属性和方法时,就可以将相同的东西抽取到一个父类中
2.当A 类完全拥有B 类中的属性和方法时,可以考虑让B类继承A类(不一定)
xx是xx 继承;student 是Person
xx拥有xx;组合
--实例变量修饰符:
作用范围:
@public : (公开的)在有对象的前??下,任何地方都可以直接访问。
@protected: (受保护的)只能在当前类和子类的对象方法中访问
@private: (私有的)只能在当前类的对象方法中才能直接访问
@package: (框架级别的)作用域介于私有和公开之间,只要处于同一个框架中就可以直接通 过变量名访问
@interface Person : NSObject { @public //公开的, 在任何地方通过实例对象都可以访问 int _age; @private //私有的,表示只能在当前类中使用 NSString *_name; @protected //受保护类型,表示只能在当前类和子类中访问 float _weight; } -(void)run; @end
实例变量作用域使用注意事项
(1)在@interface @end之间声明的成员变量如果不做特别的说明,那么其默认是protected 的。
(2)一个类继承了另一个类,那么就拥有了父类的所有成员变量和方法,注意所有的成员变量它 都拥有,只是有的它不能直接访问。
五.私有变量&私有方法:
默认情况下实例变量属于@protected修饰.
定义格式:
//在.m文件当中定义 @implementation Person : NSObject { int age; // 私有变量 } // 不在.h文件中声明, 只在.m文件中实现 -(void)run{ NSLog(@"我是私有方法"); } @end
私有方法只能在当前文件中使用, 不能被子类继承.
--------------多态----------------
什么是多态:多态就是某一类事物的多种形态;
程序中的多态:不同的对象以自己的方式响应相同名称方法的能力称为多态
父类的指针指向了子类的方法
表现形式: Animal *ani = [Dog new];
多态条件:1.有继承关系 2.有方法的重写
1.好处:
简化了编程接口。它容许在类和类之间重用一些习惯性的命名,而不用 为每一个新加的函数命名一个新名字。
简化代码
如果函数/方法参数中使用的是父类的类型,可以传入父类、子类的对象
局限性:父类类型的变量,不能直接调用子类特有的方法。必须强转为子类类型的变量,才能直接调用子类特有的方法
2.多态代码实现:
//实例化猫的对象
Animal *animal = [Cat new]; //父类的指针指向子类对象;
[animal eat];
//实例化狗的对象
animal = [Dog new]; //父类的指针指向子类对象。
[animal eat];
3.多态的原理
动态绑定:
动态类型能使程序直到执行时才确定对象所属类型
动态类型绑定能使程序直到执行时才确定要对对象调用的实际方法
OC不同于传统程序设计语言,它可以再运行时加入新的数据类型和新的程序模块:动态类型 识别,动态绑定,动态加载
id类型:是一种通用的对象类型,它可以用来存储任何类的对象
通用指针类型,弱类型,编译时不进行类型检查
4.多态注意点:
1) 如果存在多态,父类是可以访问子类特有的方法
假设子类Dog 有一个特有的方法bark
Animal *an2 = [Dog new]; //编译时看等号左边,运行时看等号右边
[(Dog*)an2 bark]; //把父类的指针,强制类型转换
2) 如果不存在多态,父类是不可以访问子类特有的方法的
Animal *an3 = [Animal new];
[(Dog*)an3 bark]; //错误的,不能强制转换