黑马程序员——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在跑,在这里看出来了多态的好处,可
以用一个方法传递不同的参数,调用不同类中相同方法。
总结:面向对象虽然符合人的思维,但是在初接触时会容易晕,好多对象调过来调过去,需要
加强对面向对象的理解,我会努力的。
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在跑,在这里看出来了多态的好处,可
以用一个方法传递不同的参数,调用不同类中相同方法。
总结:面向对象虽然符合人的思维,但是在初接触时会容易晕,好多对象调过来调过去,需要
加强对面向对象的理解,我会努力的。
相关文章推荐
- 黑马程序员—OC语言面向对象三大特性
- 黑马程序员_OC面向对象的三大特性
- 黑马程序员---OC面向对象三大特性(封装、继承、多态)
- 黑马程序员————OC面向对象_三大特性之继承与多态
- 黑马程序员——OC语言基础:面向对象三大特性,封装、继承、多态
- 黑马程序员——OC基础——面向对象的三大特性(三)
- 黑马程序员——OC语言基础——面向对象三大特性之多态
- 黑马程序员——OC面向对象三大特性——封装,继承,多态。
- 黑马程序员_OC基础04_面向对象三大特性
- 黑马程序员——OC基础——面向对象的三大特性(一)
- 黑马程序员_OC语言之面向对象的三大特性(封装、继承、多态)
- 黑马程序员——OC基础---面向对象(思想,类,对象,三大特性)
- 黑马程序员---OC--面向对象三大特性
- 黑马程序员——OC面向对象三大特性——封装,继承,多态。
- 黑马程序员————IOS学习笔记 第3篇 OC面向对象三大特性(1)
- 黑马程序员——OC语言学习——OC面向对象的三大特性:封装、继承、多态,OC字符串——NSString
- 黑马程序员_OC面向对象的三大特性之封装及OC中类方法和self的使用
- 黑马程序员————IOS学习笔记 第4篇 OC面向对象三大特性(2)
- 黑马程序员——【OC】面向对象的三大特性
- 黑马程序员————OC面向对象_三大特性之封装