您的位置:首页 > 职场人生

黑马程序员——OC—面向对象的三大特性

2015-03-22 23:41 323 查看
OC第二篇---面向对象的三大特性

OC中面向对象的三大特性是:封装、继承、多态,这三中特性让OC才真正的实现了面向

对象的思想。

一、封装set和get:

封装性是对成员变量的一种封装,在以前定义的成员变量为了让外部访问到把成员变量用

@public修饰,意思就是公开的。而封装就是杜绝这种现象发生,封装可以很好的保护内部成员

变量不能随意的访问。那么对成员变量到底怎么实现封装,就是每一个成员变量都会对应一个

set和get方法,set方法就是对成员变量赋值,get方法就是取出成员变量的值。

1.set方法的使用

作用:用来设置成员变量,可以在方法里面过滤掉一些不合理的值

命名规范:

1.方法都是以set开头,而且后面跟上成员变量名,成员变量名的首字母必须大写

2.形参名称不要跟成员变量同名

3.返回值都是void

2.get方法的使用

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

命名规范:

1.get方法的名称一般就跟成员变量同名

2.返回值都和成员变量类型相同

代码示例:

#import <Foundation/Foundation.h>

typedef enum {

SexMan,

SexWoman

} Sex;

@interface Student : NSObject

{

int _no; // 学号

Sex _sex; // 性别

}

- (void)setNo:(int)no; // 学号set,get方法

- (int)no;

- (void)setSex:(Sex)sex; // 性别set,get方法

- (Sex)sex;

@end

@implementation Student

// 学号set和get方法

- (void)setNo:(int)no{

_no = no;

}

- (int)no{

return _no;

}

// 性别的set和get方法

- (void)setSex:(Sex)sex{

-sex = sex;

}

- (Sex)sex{

return _sex;

}

@end

int main()

{

Student *s=[Student new];

[s setNo:1]; // 调用set方法

[s setSex:SexMan];

[s no]; // 调用get方法

[s sex];

return 0;

}

这样就可以防止外部直接访问成员变量了,而且我们还可以在set方法中有一些过滤的操作,有

条件的接收,set方法还有一个特别的功能,就是它可以监听成员变量的值是否改变,说白了就是只

要值改变就会来到set方法,我们可以做到实时更新数据的效果。set方法和get方法不一定配对使用,

现实中某些对象的属性是只能让人看,不可以访问的,也就是只读,比如商品的生产许可号你可以

知道,但是不能修改。

3.封装性的好处:

1.可以在set方法中进行过滤操作

2.防止外界直接访问成员变量

3.外界只能看到外表,不用在意内部的细节

二、类方法:

每一个类都会实例一个对象,从而这个对象可以完成某些行为,这些行为就是对象方法,类也有

方法,叫做类方法。当我们创建一个对象的时候就已经用到了类方法。例如:

Student *s=[Student new] 这句代码中创建了一个Student类型的新对象s,而[Student new]是利

用类Student 调用了类方法中的new方法,完成创建对象的方法。new方法存在于父类 NSObject 中定义。

1.概念:用类名直接调用的方法

2.类方法的规范:

1).以‘+’号开头

2).由类调用,对象不可以直接调用

3).没有权力访问成员变量

代码示例:

#import <Doundation/Foundation.h>

@interface Student : NSObject

- (void)print; // 对象方法

+ (void)print; // 类方法

@end

@implementation Student

- (void)print

{

NSLog(@"对象方法");

}

+ (void)print

{

NSLog(@"类方法");

}

@end

int main()

{

Student *s=[Student new];

[s print];

[Student print]; // 调用类方法

return 0;

}

这段代码中,调用了对象方法,和类方法,类方法的调用和创建对象的new方法调用一致,调用

的格式:[类名 方法名] 类方法之所以效率会高,是因为对象方法必须用对象去调用,创建对象需要

开辟存储空间,而类方法不同,直接由类去调用,不需要耗费任何内存。并且类方法名和对象方法名

可以一样,互不影响。

3.总结一下类方法和对象方法的区别:

类方法:

1).以‘+’号开头

2).只能用类名调用,对象不能调用

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

对象方法:

1).以减号'-'开头

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

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

4. 类方法和对象方法的注意点:

1).对象方法只能由对象去调用。

2).类方法只能由类调用。

3).类方法和对象方法可以同名。

三、self实用:

1.self作用:self其实是一个指针,用在方法中,它可以访问成员变量,用来区分同名的局部变量。

2.使用场景:

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

3.如何使用:

1).使用 "self->成员变量名" 访问当前方法调用的成员变量

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

代码示例:

#import <Foundation/Foundation.h>

@interface Dog : NSObject

// 狗叫和跑方法

- (void)bark;

- (void)run;

@end

@implementation Dog

- (void)bark

{

NSLog(@"汪汪汪");

}

- (void)run

{

[self bark];

/ / NSLog(@"汪汪汪");NSLog(@"跑跑跑");

}

@end

int main()

{

Dog *d = [Dog new];

[d run];

return 0;

}

代码中在对象方法run中 [self bark]; 是调用当前对象的bark方法,也可以调用成员变量,可

以完全理解为self就是一个对象。注意一点的就是self调用时只能调用当前对象的方法,总结一点

理解为:self在类方法中就代表self指向类,self在对象方法中就代表self指向对象。

4.self死循环注意:

- (void)test

{

[self test];

}

四、继承:

在以前的代码中,声明一个类必须要继承后面的NSObject 这是因为NSObject是基础类,很多

基础方法都在这个类中,那么说一说什么是继承。

如果某些类中都有相同的成员变量和方法,就可以抽出来一个父类,然后子类同时继承这个父

类,子类中会拥有父类的全部成员变量和方法,因此继承让程序减少代码的重复,让这些垃圾代码

远离我们。

1.继承的特点:

1).子类会拥有父类所有的成员变量和方法

2).子类可以扩充自己的成员变量和方法

3).单继承,不允许多继承

2.子类访问方法:

子类调用父类方法时,会先检测子类中是否有此方法,有就访问子类的方法,如果没有则去父类中

找有无此方法,如果有就调用父类的方法。

3.注意点:

1).子类和父类不能有相同的成员变量

2).子类可以和父类有相同的方法3.子类不能直接访问父类的@private变量

4.方法的重写:

1). 子类中可以有和父类相同的方法,叫做方法的重写

2).重写的方法不能再调用父类的方法,可以通过[super 方法名] 调用

代码示例:

#import <Foundation/Foundation.h>

@interface Person : NSObject

{

int _age;

}

// 年龄set和get方法

- (void)setAge:(int)age;

- (int)age;

// 跑方法

- (void)run;

+ (void)test;

@end

@implementation Person

+ (void)test

{

NSLog(@"Person+test");

}

- (void)run

{

NSLog(@"person---跑");

}

// 年龄set和get方法

- (void)setAge:(int)age

{

_age = age;

}

- (int)age

{

return _age;

}

@end

// 不允许子类和父类拥有相同名称的成员变量

@interface Student : Person

{

int _no;

}

+ (void)test2;

@end

@implementation Student

- (void)run

{

// 方法的重写

NSLog(@"student---跑");

[super run]; // 调用父类中的run方法

}

+ (void)test2

{

[self test];

}

@end

int main()

{

[Student test2];

Student *s = [Student new];

[s run];

return 0;

}

代码中Student继承父类Person,首先调用Student类方法test2,而 [self test] 这句首先会在

Student中找类方法test,如果找不到会从父类Person中找,因此输出 Person+test 再然后调用

对象s的run方法,在子类中也可以定义一个和父类同名的方法,这个叫做方法的重写,也就是说

会输出子类的 student---跑

那么子类可以重写父类的方法,如果在重写之后还想调用父类的方法可以通过[super 方法名]

例如上个代码中的:[super run]; 运行的原理是:调用方法时,优先在当前类中找,找不到则通过

superclass指针去父类中找,找到了则会调用父类的方法。

5.继承的好处和坏处:

好处:

1).不改变原来模型的基础上,拓充方法

2).建立了类与类之间的联系

3).减少代码重复性

坏处:耦合性强,父类一旦修改删除,子类会受到很大影响

五、多态:

最后一种特性是多态,多态是适用于对象,就是对象有多种形态。多态在运用时有个前提,那就

是必须在继承的情况下才会有多态。

1.多态的特点:

1).没有继承就没有多态

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

3).如果函数参数中使用的是父类类型,实参可传父类/子类

2.多态的体现:

Person *p = [Student new];

p->age = 100;

[p walk];

子类对象赋值给父类指针

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

3.多态的原理:

动态绑定:在运行时根据对象的类型确定动态调用的方法

示例代码:

#import <Foundation/Foundation.h>

@interface Person : NSObject

{

int _age;

}

// 年龄的set和get方法

- (void)setAge:(int)age;

- (int)age;

- (void)run;

@end

@implementation Person

// 年龄的set和get方法

- (void)setAge:(int)age

{

_age = age;

}

- (int)age

{

return _age;

}

- (void)run

{

NSLog(@"Person在跑");

}

@end

@interface Student : Person

- (void)run;

@end

@implementation Student

- (void)run

{

NSLog(@"Student在跑");

}

@end

void run(Person *p)

{

[p run];

}

int main()

{

Person *p1 = [Student new];

Student *p2 = [Student new];

run(p1);

run(p2);

return 0;

}

在这段代码中,用父类 Person 创建了 Student 对象,但是在调用方法时会动态绑定检测对

象的真实形态,真实形态是Person 因此输出的是Person在跑,在这里看出来了多态的好处,可

以用一个方法传递不同的参数,调用不同类中相同方法。

总结:面向对象虽然符合人的思维,但是在初接触时会容易晕,好多对象调过来调过去,需要

加强对面向对象的理解,我会努力的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐