【iOS】—— 类的继承

一.继承的概念

继承是面向对象的三大特征之一,也是实现软件复用的重要手段,Objective-C的继承具有单继承特点,每个子类只有一个父类。 继承可以使得子类具有父类的属性和方法或者重新定义、追加属性方法等。
例如:车和轿车、卡车的关系,轿车和卡车继承了车,它们是车的子类。
继承

因为子类是一种特殊的父类,因此,父类包含的范围总比子类包含的范围要大,所以可以认为父类是大类,子类是小类。


二.继承的好处

  • 提高了代码的复用性,能够大大缩短开发周期;
  • 提高了代码的维护性;
  • 让类和类之间产生了关系,是多态的前提;

三.一切从基类(NSObject)开始

继承就像一个倒过来的树一样,不断地分叉,这些树叉最初都是由数的根部分出来的,OC中的这个根就是NSObject类,所以我们以前定义类的形式为:

@interface 类名: NSObject
{
       //成员变量声明
}
       //方法声明
@end

即该类的父类为NSObject,该类就继承了NSObject。

而继承的子类继承父类的语法如下:

@interface 类名: 父类
{
       //成员变量声明
}
       //方法声明
@end

例如:

@interface SubClass: SuperClass
{
       //成员变量声明
}
       //方法声明
@end

从上面的语法格式看,定义子类的语法非常简单,只需在原来类的定义上增加“:SuperClass”即可,即表明该子类"SubClass"继承了"SuperClass"。

四.子类中只可以访问父类中interface中声明的变量和方法。

我们定义一个父类ClassA,它在interface中有变量x和方法initVar:

@interface ClassA: NSObject
{
   int x;
}
- (void) initVar;
@end

@implementation
{
   int y;
}
- (void) initVar {
   x = 100;
   y = 101;
}
@end

我们再定义一个子类ClassB,继承的ClassB中增加一个方法printVar来打印变量,printVar方法也就为子类扩展的新方法

@interface ClassB: ClassA 
- (void) printVar;
@end

@implementation
- (void) printVar {
   NSLog(@"x = %i", x);
   //NSLog(@"y = %i", y);   //error,因为y是在父类的impletation中定义的,所以子类无法访问y。
}
@end

y会报错:
报错

子类只能访问父类interface中声明的变量x,像implementation中的y变量在子类中是不能访问的。子类ClassB自动继承了ClassA中的initVar方法,是可以直接访问的,我们看main方法中的调用:

int main(int argc, char *argv[]) {
   @autoreleasepool {
      ClassB* obj = [[ClassB alloc] init];
      [obj initVar];
      [obj printVar];
   }
   return 0;
}

输出为:
输出


五.程序如何找到正确的方法

这个很简单,当我们调用一个对象的方法时,先在这个对象的类和类别中找,如果找不到,就到父类和父类的类别中找,如果还找不到就到父类的父类和其类别中找,直到找到为止。注意,OC中为单继承,每个类只有一个父类,所以在这个唯一的父类中找即可。


六.重写父类的方法

继承常做的两件事:扩展方法和覆盖。继承不能减少或者删除父类的方法,但可以覆盖重写父类在interface中声明的方法。之前我们说过了OC如何查找正确方法,现在本身的类和类别中找,找到后就可以调用了,这就是覆盖父类的前提。
同样看之前写过的ClassA和ClassB:

@interface ClassA: NSObject
{
   int x;
}
- (void) initVar;
@end

@implementation
- (void) initVar {
   x = 100;
}
@end

我们在子类ClassB中重写initVar方法:

@interface ClassB: ClassA 
- (void) printVar;
@end

@implementation
- (void) initVar {
   x = 200;
}
- (void) printVar {
   NSLog(@"x = %i", x);
}
@end

在main中调用一下看看x的值:

int main(int argc, char *argv[]) {
   @autoreleasepool {
      ClassB* obj = [[ClassB alloc] init];
      [obj initVar];
      [obj printVar];
   }
   return 0;
}

输出为:
输出

此时ClassB实际上有一个变量x,两个方法initVar和printVar可用。


七.super关键字

如果需要在子类方法中调用父类被覆盖的实例方法,可使用super关键字来调用父类被覆盖的实例方法。
同样看之前写过的ClassA和ClassB:

@interface ClassA: NSObject
{
   int x;
}
- (void) initVar;
@end

@implementation
- (void) initVar {
   x = 100;
}
@end

我们在子类ClassB中重写initVar方法:

@interface ClassB: ClassA 
- (void) ClassAinitVar;
- (void) printVar;
@end

@implementation
- (void) ClassAinitVar {
   //在子类方法中通过super显式调用父类被覆盖的实例方法
   [super initVar];
}
- (void) initVar {
   x = 200;
}
- (void) printVar {
   NSLog(@"x = %i", x);
}
@end

在main中调用一下看看x的值:

int main(int argc, char *argv[]) {
   @autoreleasepool {
      ClassB* obj = [[ClassB alloc] init];
      [obj initVar];
      [obj printVar];
      [obj ClassAinitVar];
      [obj printVar];
   }
   return 0;
}

输出为:
输出

super是Objective-C提供的一个关键字,super用于限定该对象调用它从父类继承得到的属性和方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值