您的位置:首页 > 编程语言 > C语言/C++

黑马程序员_OC语言的面向对象特性

2014-03-21 16:40 302 查看
iOS,Android,Java培训,期待与您的交流

面向对象的三大特征是封装、继承和多态。OC语言也支持面向对象的三大特征,OC提供了@private、@package、@protected、@public等访问控制符来实现封装;OC也允许子类来继承父类,并且支持多态。

1 封装

封装指的是將对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法对内部信息的操作和访问。OC的封装特性需要通过使用访问控制符来实现。

1.1 访问控制符

1、@private:当前类访问权限。如果类的成员变量使用@private访问控制符来限制,则这个成员变量只能在当前类的内部被访问。这个访问控制符用于彻底隐藏成员变量。在类的实现部分定义的成员变量相当于默认使用这种访问权限。

2、@package:框架类访问权限。如果类的成员变量使用@package访问控制符来限制,则当前类或者同一框架中的其他类能够访问这个成员变量。这个访问控制符用于部分隐藏成员变量。

3、@protected:子类访问权限。如果类的成员变量使用@protected访问控制符来限制,则当前类或者其子类能够访问这个成员变量。这个访问控制符用于部分隐藏成员变量。

4、@public:公共访问权限。如果类的成员变量使用@public访问控制符来限制,则所有的类都能够访问这个成员变量。这个访问控制符用于彻底暴露成员变量,一般不建议这么做。

1.2 set和get方法

类里面的绝大部分成员变量应该使用@private进行限制,提供set和get方法访问该成员变量。

set方法

1.作用: 提供一个方法给外界设置成员变量值,可以在方法里面对参数进行相应过滤

2.命名规范:

1> 方法名必须以set开头

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

3> 返回值一定是void

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

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

get方法

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

2.命名规范:

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

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

3> 不需要接收任何参数

@interface Student : NSObject
{
@private
int age;
}

- (void)setAge:(int)newAge;  //set方法,用来改变age的值
- (int)age;  //get方法,用于获取age的值

@end

@implementation Student

// set方法的实现
- (void)setAge:(int)newAge
{
// 对传进来的参数进行过滤
if (newAge <= 0)
{
newAge = 1;
}

age = newAge;
}

- (int)age
{
return age;
}

@end
2 继承

继承是面向对象的三大特征之一,也是实现软件复用的重要手段。OC的继承具有单继承的特点,每个子类只有一个直接父类。

继承的好处:

1> 抽取重复代码

2> 建立了类之间的关系

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

/********Animal的声明*******/
@interface Animal : NSObject
{
int _age;
double _weight;
}

- (void)setAge:(int)age;
- (int)age;

- (void)setWeight:(double)weight;
- (double)weight;
@end

/********Animal的实现*******/
@implementation Animal
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}

- (void)setWeight:(double)weight
{
_weight = weight;
}
- (double)weight
{
return _weight;
}
@end

/********Dog*******/
// : Dog 继承了Animal,相当于拥有了Animal里面的所有成员变量和方法
// Animal称为Dog的父类
// Dog称为Animal的子类
@interface Dog : Animal
@end

@implementation Dog
@end

/********Cat*******/
@interface Cat : Animal
@end

@implementation Cat
@end

int main()
{
Dog *d = [Dog new];

[d setAge:10];

NSLog(@"age=%d", [d age]);
return 0;
}
2.1 重写父类方法

子类重新实现父类中的某个方法,覆盖父类中的方法叫做重写。子类重写父类的方法需要注意以下几点

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

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

3> 调用某个方法时,优先去当前类中找,如果找不到,去父类中找

// Person
@interface Person : NSObject
{
int _age;
}

- (void)setAge:(int)age;
- (int)age;

- (void)run;

+ (void)test;

@end

@implementation Person

+ (void)test
{
NSLog(@"Person+test");
}

- (void)run
{
NSLog(@"person---跑");
}

- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
@end

// 不允许子类和父类拥有相同名称的成员变量
// Student
@interface Student : Person
{
int _no;
// int _age;
}

+ (void)test2;

@end

@implementation Student
// 重写:子类重新实现父类中的某个方法,覆盖父类以前的做法
- (void)run
{
NSLog(@"student---跑");
}

+ (void)test2
{
[self test];
}
@end

int main()
{
[Student test2];
//    Student *s = [Student new];
//
//    [s run];
return 0;
}
2.2 super关键字

如果需要在子类方法中调用父类的方法,可使用super关键字。super处在对象方法中,那么就会调用父类的对象方法; super处在类方法中,那么就会调用父类的类方法。

// 僵尸
@interface Zoombie : NSObject
- (void)walk;

+ (void)test;
- (void)test;

@end

@implementation Zoombie
- (void)walk
{
NSLog(@"往前挪两步******");
}

+ (void)test
{
NSLog(@"Zoombie+test");
}

- (void)test
{
NSLog(@"Zoombie-test");
}
@end

// 跳跃僵尸
@interface JumpZoombie : Zoombie
+ (void)haha;
- (void)haha2;
@end

@implementation JumpZoombie

+ (void)haha
{
[super test];
}

- (void)haha2
{
[super test];
}

- (void)walk
{
// 跳两下
NSLog(@"跳两下");

// 走两下(直接调用父类的walk方法)
[super walk];
//NSLog(@"往前挪两步----");

}
@end

int main()
{
//[JumpZoombie haha];
JumpZoombie *jz = [JumpZoombie new];

[jz haha2];

return 0;
}
3 多态

OC指针类型的变量有两个,一个是编译时的类型,一个是运行时的类型,编译时的类型是由声明该变量时使用的类型决定,运行时的类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就出现多态。

// 动物
@interface Animal : NSObject
- (void)eat;
@end

@implementation Animal
- (void)eat
{
NSLog(@"Animal-吃东西----");
}
@end

// 狗
@interface Dog : Animal
- (void)run;
@end

@implementation  Dog
- (void)run
{
NSLog(@"Dog---跑起来");
}
- (void)eat
{
NSLog(@"Dog-吃东西----");
}
@end

// 猫
@interface Cat : Animal

@end

@implementation Cat
- (void)eat
{
NSLog(@"Cat-吃东西----");
}
@end

// 这个函数是专门用来喂动画
//void feed(Dog *d)
//{
//    [d eat];
//}
//
//void feed2(Cat *c)
//{
//    [c eat];
//}
//

// 如果参数中使用的是父类类型,可以传入父类、子类对象
void feed(Animal *a)
{
[a eat];
}

int main()
{
// NSString *d = [Cat new];
// [d eat];

/*
Animal *aa = [Dog new];
// 多态的局限性:父类类型的变量 不能 用来调用子类的方法
//[aa run];

// 将aa转为Dog *类型的变量
Dog *dd = (Dog *)aa;

[dd run];
*/

//Dog *d = [Dog new];

//[d run];

/*
Animal *aa = [Animal new];
feed(aa);

Dog *dd = [Dog new];
feed(dd);

Cat *cc = [Cat new];
feed(cc);
*/

/*
// NSString *s = [Cat new];
Animal *c = [Cat new];

NSObject *n = [Dog new];
NSObject *n2 = [Animal new];

// 多种形态
//Dog *d = [Dog new]; // Dog类型

// 多态:父类指针指向子类对象
Animal *a = [Dog new];

// 调用方法时会检测对象的真实形象
[a eat];
*/
return 0;
}
iOS,Android,Java培训,期待与您的交流
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: