黑马程序员—OC语言基础—面向对象的三大特性(2)

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

一、继承

1.继承的基本概念与用法

继承,光看这个词,我们就能明白大概意思,就是说有一个新东西能具有一种老东西的特性。接下来我们具体来了解一下面向对象的继承是怎么继承的,有什么样的好处。

在OC中,我们一般说的继承,是指类的继承。假设有类A,那么如果类B的属性与类A相同(即代码一样),这种情况我们考虑用继承,类B继承类A。

之前我们写程序时一直用的

@interface Person : NSObject
这句中就是利用了继承,Person类继承了NSObject基类。:是继承的标示符。

在这里,Person就称为NSObject的子类,NSObject就称为Person类的父类。

@interface Student : Person
@end

这里的意思就是Student类继承了Person类的所有属性。

2.继承的好处

1)抽取重复冗余的代码

2)建立了类之间的关系

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

注:基本上所有类的根类都是NSObject

3.继承的缺点

继承最大的缺点就是耦合性太强,一旦父类发生变化或者丢失,那么子类也不能存在下去,依赖性太强。


总结:

1.编译器是从上到下编译的,因此父类要写在前面。但如果把implementation部分放后面是OK的,只要声明在前面就行了。

2.Java中允许父类与子类中有相同成员名称的变量。而OC中是不允许的。

3.当运行方法时,检测的顺序是:本对象中查找方法---->父类中查找----->再往上一级查找

4.与成员变量定义规范不同,如果子类与父类有相同的方法实现是允许的。不过子类的方法会覆盖掉父类的方法,这也叫做重写。


二、组合

当类B具有类A的属性时,但类B又不属于类A的范畴,那么这时候我们就要用到组合。

组合的格式为:

A *_a;

//类A
{
    int _age;
    int _no;
}
//如果类B要有类A的属性,但又不属于类A
//类B
{
    A *_a;
    int _weight;
}


三、super关键字

super的作用是直接调用父类的某个方法,并且和self关键字相同的是:(1)super处在对象方法中,就调用父类的对象方法;(2)super处在类方法中,就调用父类的类方法。

一般super关键字所使用的场合是,当子类重写父类方法时,想保留父类的一些行为时,就需要用到super关键字。

/*
 僵尸
 跳跃僵尸、舞王僵尸、铁桶僵尸
*/
#import<Foundation/Foundation.h>
@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(@"跳两下");
    [super walk];
}
@end
int main()
{
    JumpZoombie *jz = [[JumpZoombie alloc] init];
    [jz walk];
    [jz haha2];
}

在这里[super test];就可以直接调用父类中的对象方法与类方法。


四、多态

多态的意思就是允许子类类型的对象赋值给父类类型的指针,如果参数中使用的时父类类型,可以传入父类、子类对象,这是多态的一个方便之处。

下面我们用一个例子来体验一下多态:

#import <Foundation/Foundation.h>  
// Animal类
@interface Animal : NSObject  
- (void)eat;  
@end  
  
@implementation Animal  
- (void)eat  
{  
    NSLog(@"Animal--吃东西");  
}  
@end  
  
// Dog类继承Animal类
@interface Dog : Animal  
- (void)run;  
@end  
  
@implementation  Dog  
- (void)run  
{  
    NSLog(@"Dog--跑起来");  
}  
- (void)eat  
{  
    NSLog(@"Dog--吃东西");  
}  
@end  
  
// Cat类继承Animal类
@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];// 调用方法时会检测对象的真实形象,在Animal中有方法eat,虽然Dog内也有,但是会调用前者
    return 0;  
}  

所以多态的总结有下面几点:

1.没有继承就没有多态

2.父类类型的指针指向子类对象

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

局限性: 父类类型的变量 不能 直接调用子类特有的方法。必须强转为子类类型变量后,才能直接调用子类特有的方法





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值