------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、继承
在面向对象的过程中,若类A继承类B, 则类A有B的全部属性和方法。B是A的父类,A是B的子类。例如:猫有一般动物的属性,则动物可以使猫的父类;学生具有人的属性,则学生可以使人的子类,学生可以继承人....继承是OC面向对象最基本的特点。如之前见到的 Student : NSObject ,其中NSLog就是student的父类,因此student就可以使用方法new来创建student的对象。而且基本上所有类的根类是NSObject
书写格式:子类名:父类名
使用注意:
不允许子类与父类有相同名称的成员变量
使用场合:
1>当两个类有相同的属性和方法时,就可以将相同的属性和方法抽取到一个父类中
2>当一个类拥有另外一个类的属性和方法,可以考虑让让后者继承前者
继承的好处:
1> 抽取重复代码
2> 建立了类之间的关系
3> 子类可以拥有父类中的所有成员变量和方法
坏处:
类与类之间的耦合性太强,即太相互依赖,一旦某个父类发生变化或者丢失,则子类进行继承时会出错
二、重写
子类重新实现父类中的某个方法,覆盖以前的做法叫做重写,因此前提必须是在继承的环境下。
注意:1>父类必须声明在子类的前面
2>类不能拥有和父类相同的成员变量
3>调用某个对象的方法时,优先当前类去找,如果找不到去上一级类中去找,即可以有相同的方法名,在对象使用方法时优先从调用的它的类找,如果没有则从父类找到方法
三、组合
在一些场合中继承未必能用,如:成绩类有英语成绩、数学成绩,学生类也包含以上属性,显然有相同的属性,若用继承的思想则认为学生继承了成绩,很显然这不符合逻辑,因此,在一些环境下想要保证性能,但不能用继承,因此可以考虑组合。组合是类A将类B作为它的成员变量,因此A也可以使用B的成员变量和属性。
组合:把一个类拥有另一个类的属性
继承的使用场合
1> 当两个类拥有相同属性和方法的时候,就可以将相同的东西抽取到一个父类中
2> 当A类完全拥有B类中的部分属性和方法时,可以考虑让B类继承A类。注意:有时候不符合逻辑,则要考虑组合!
如下是继承和组合的表达:
A
{
int _age;
int _no;
}
B : A
{
int _weight;
}
继承:B 是 A
组合:B 拥有 A
组合的形式
A
{
int _age;
int _no;
}
B
{
A *_a;
int _weight;
}
四、self关键字
1>谁调用了当前方法,self就代表谁
如:self出现在对象方法中,self就代表对象
self出现在类方法中,self就代表类
2> 在对象方法利用"self->成员变量名"访问当前对象内部的成员变量
3>注意self的使用会引发死循环,方法自己指向自己会引起死循环,如:
- (void)test
{
NSLog(@"调用了-test方法");
[self test];
}//会引起死循环
@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是对象方法,在[ d run ]时,则self指向对象d的方法bark。
五、super 关键字
在用继承来描述对象时,有时方法中可能在某些父类方法的基础上添加新东西,在此可以用super关键字,与self类似,是指针。
1.super的作用:
1>直接调用父类中的某个方法
2>super处在对象方法中,那么就会调用父类的对象方法;super处在类方法中,那么就会调用父类的类方法
2.使用场合:
子类重写父类的方法时想保留父类的一些行为。
例如:植物大战僵尸中僵尸是父类 而跳跃僵尸、舞王僵尸、铁桶僵尸都可以继承僵尸,在继承走是时可以继承僵尸走,但是还要跳跃、跳舞等动作
代码:
// 僵尸
@interface Zoombie : NSObject
- (void)walk;
@end
@implementation Zoombie
- (void)walk
{
NSLog(@"往前挪两步******");
}
@end
// 跳跃僵尸
@interface JumpZoombie : Zoombie
@end
@implementation JumpZoombie
- (void)walk
{
// 跳两下
NSLog(@"跳两下");
// 走两下(直接调用父类的walk方法)
[super walk];
}
@end
跳跃僵尸就是在僵尸的基础上添加了跳两下的动作,然后在使用super walk]就可以实现父类的walk了。
六、多态
1.允许子类类型的对象赋值给父类类型的指针,如果参数中使用的是父类类型,可以传入父类、子类对象,这是多态的好处。
#import <Foundation/Foundation.h>
// 动物
@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(Animal *a)
{
[a eat];
}
int main()
{
Animal *aa = [Animal new];
feed(aa);
Dog *dd = [Dog new];
feed(dd);
Cat *cc = [Cat new];
feed(cc);
// 多态:父类指针指向子类对象
Animal *a = [Dog new];
[a eat];<span style="font-family: Arial, Helvetica, sans-serif;">// 调用方法时会检测对象的真实形象,在Animal中有方法eat,虽然Dog内也有,但是会调用前者</span>
return 0;
}
2.局限性:父类类型的变量不能用来调用子类的方法,必须强转为子类类型变量后,才能直接调用子类特有的方法。如下:
Animal *aa = [Dog new];
[aa run];
则可以将aa转化为dog指针的类型,之后便可以调用子类的方法
Dog *dd = (Dog *)aa;
[dd run];