黑马程序员---OC面向对象三大特性(封装、继承、多态)

来源:互联网 发布:传奇赌博数据分析器 编辑:程序博客网 时间:2024/05/16 10:15

———Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ———

一:封装

因为@public的成员可以被随意赋值,这样就导致了有些成员变量的不合理性,所以我们把成员变量封装起来,外界不能随意访问和修改,这样就提高了程序的安全性和合理性。OC中使用set方法和get方法来管理成员的访问(类似机场的安检、水龙头过滤,过滤掉不合理的东西),比如僵尸的生命值不能为负数。

set方法

 1.作用:提供一个方法给外界设置age属性值,可以在方法里边对参数进行相应过滤

 2.命名规范:

 1>方法名必须以set开头

 2>set后面跟上成员变量的名称、成员变量的首字母大写

 3>返回值一定是void

 4>一定要接收一个参数,而且参数类型跟成员变量类型一致

 5>形参的名称不能跟成员变量名一样

get方法

 1.作用:返回对象内部的成员变量

 2.命名规范:

    1>肯定有返回值,返回值类型肯定与成员变量类型一致

    2>方法名跟成员变量名一样

    3>不需要接受任何参数

如果定义一个int类型的变量no,要求是只读。

只读(readonly:只允许外界访问我的no,不允许外界修改我的no

    int no;// 所以只需要提供get方法就可以了

代码示例:

#import <Foundation/Foundation.h>// 声明@interface Car : NSObject{    int _wheels; // 轮子个数}/*set方法*/- (void) setWheels:(int)wheels;/*get方法*/- (int) wheels;@end@implementation Car// set方法的实现- (void) setWheels:(int)wheels{    // 对外面传进来的轮子数进行过滤    if (wheels<=0)    {        wheels = 1;    }        _wheels = wheels;}// get方法的实现- (int) wheels{    return _wheels;}@end
如果要访问成员变量时,那么就调用对象的set和get方法:

[car setWheels:4]; // 设置轮子个数为4

[car wheels]; // 获取轮子个数

封装的好处

过滤不合理的值

屏蔽内部的赋值过程

让外界不必关注内部的细节

成员变量的命名规范

成员变量都以下划线 _ 开头

可以跟get方法的名称区分开

可以跟其他局部变量区分开,一看到下划线开头的变量,肯定是成员变量

OC弱语法

一旦运行过程中出错就会闪退

 函数和方法没有声明和实现,直接调用,运行时出错:

-[Person test]: unrecognized selector sent to instance 0x7fc591c098b0

 Person对象发送了一个不能识别的消息:test

int main(){    Person * p=[Person new];    //OC是在运行过程中才会检测对象有没有实现相应的方法,编译时并不会报错    [p test];    return 0;}

如果只有声明没有实现,编译时只是警告,运行时才会显示错误

如果只有实现,没有声明,编译只有警告,运行不报错,有结果

类方法

基本概念

直接可以用类名来执行的方法(类本身会在内存中占据存储空间,里面有类\对象方法列表)

类方法和对象方法对比

对象方法

1->以减号-开头

2->只能让对象调用,没有对象,这个方法根本不可能被执行

3->对象方法能访问实例变量(成员变量)

类方法

1->以加号+开头

2->只能用类名调用,对象不能调用

3->类方法中不能访问实例变量(成员变量)

类方法的好处和使用场合

    1>不依赖于对象,执行效率高

    2>能用类方法尽量用类方法

    3>场合:当方法内部不需要使用到成员变量时,就可以改为类方法

可以允许类方法和对象方法同名

工具类:基本没有任何成员变量,里面的方法基本都是类方法

self关键字

self概念:是一个指针,指向当前对象(方法调用者),谁调用了当前方法,self就代表谁

     *self出现在对象方法中,self就代表对象

     *self出现在类方法中,self就代表类

作用

对象方法中可以用 "self->成员变量名访问当前对象内部的成员变量

使用 "[self 方法名];" 来调用方法(对象方法\类方法)

成员变量和局部变量同名

当成员变量和局部变量同名时,采取就近原则,访问的是局部变量

用self访问成员变量,区分同名的局部变量

使用细节

出现的地方:所有的OC方法中(对象方法\类方法),不能出现在函数中

常见错误

低级错误:用self去调用函数

类方法中用self调用对象方法,对象方法中用self调用类方法

self死循环

示例:

- (void)test{    NSLog(@"调用了-test方法");    //[self test];//发生死循环}+ (void)test{    NSLog(@"调用了+test方法");    //[self test];//发生死循环}

二:继承

1.继承的好处:

 1>抽取重复代码

 2>建立了类之间的关系

 3>子类可以拥有父类中的所有成员变量和方法

 4>不改变原来模型的基础上,拓充方法

 2.注意

 1>基本上所有类的根类都是NSObject,包含了一些常用方法,比如+new

 2>OC是单继承

继承专业术语;

父类\超类  superclass

子类  subclass\subclasses

3.方法重写

1.重写:子类重写实现父类中的某个方法:覆盖父类以前的做法

 注意

 1>父类必须声明在子类的前面

 2>子类不能拥有和父类相同的成员变量名

 3>调用某个方法时,优先去当前类\对象中找,如果当前对象中没有的话就去父类中去找

 2.坏处:耦合性太强

super关键字

super的作用

 1.直接调用父类中的某个方法

 2.super处在对象中,那么就会调用父类的对象方法

    super处在类方法中,那么就会调用父类的类方法

 3.使用场合:子类重写父类的方法时想保留父类中的一些行为

继承的使用场合:

 1>当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中

 2>A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A

 继承: XX XXX

 组合: XX拥有 XXX

不是所有的都适用继承,谨慎使用

三:多态

多态 (某一类事物的多种形态,OC对象具有多态性

 1.没有继承就没有多态

 2.代码的体现:父类类型的指针指向子类对象

 3.好处:如果函数\方法参数中使用的是父类类型,可以传入父类、子类对象

 4.局限性:父类类型的变量不能直接调用子类特有的方法

多态的体现

Person *p = [Student new]; // 父类Person指针,指向子类Student对象

p->age = 100;

[p walk];

子类对象赋值给父类指针

父类指针访问对应的属性和方法

多态的好处

用父类接收参数,节省代码

如果参数中使用的是父类类型,可以传入父类、子类对象

void feed(Animal *a){    [a eat];}

多态的局限性

不能访问子类的属性(可以考虑强制转换)

Animal *a=[Dog new];

    //多态的一个限制:不能用父类指针调用子类方法

    //[a run];  // 编译器警告

    Dog *dd=(Dog *)a;//a强制转为Dog*型的变量

    [dd run]; 

多态的细节

动态绑定:在运行时根据对象的类型确定动态调用的方法即调用方法时会检测到对象的真实形象

NSString的简单使用

字符串的快速创建

NSString *name = @”zy”;

使用%@输出字符串

NSLog(@“我的名字是%@”,  name);

C语言方式:

char *name="itcast";

NSLog(@"%s",name);

创建OC字符串的另一种方式:

NSString *newStr=[NSString <span style="color:#ff0000;">stringWithFormat</span>:@"my age is %d and no is %d and name is %@",age,no,name];NSLog(@"------%@",newStr);NSLog(@"%ld",[newStr length]);
0 0
原创粉丝点击