1、OC中如果类A继承类B,B就成为A的父类。那么B的成员全部属于A的成员。相当于A全部拥有了B的所有成员(所有变量与所有方法)。即子类拥有父类中所有的成员变量和方法。

2、继承的使用场合:

(1)如果有两个或者两个以上的类含有很多相同的成分(成员变量/方法相同)。那么就可以把它们相同的部分提取到一个单独的类中,让这些相似的类继承于它。继承的实质就是把多个类中相同的代码抽出来放到一个单独的类中,然后让这些多个类继承于它。

(2)当A类拥有B类中的部分属性和方法时,可以考虑让B类继承A类。

(3)当B是A的一种时,用继承,即B继承A。当B拥有A,A是B的一个组成部分时。继承是一种,即种类的关系;而组合是一部分,即拥有的关系。即当XXX是XX时用继承,当XXX拥有XX时用组合。

3、继承的好处:抽取重复的代码。建立了类之间的关系。

4、父类中必须继承自NSObject类,如果不继承这个类  任何类都没有创建对象的能力。当父类继承了NSObject,子类直接继承父类即可,相当于间接的继承了NSObject。(基本上所有的类都继承自NSObject根类,还有一根类NSProxy但基本上用不着)。

5、在OC类的继承中,直接继承NSObject的基类内部会有被加载进来的NSObject类指针(Superclass地址),即这个基类Superclass指针的值指向被加载进来的NSObject类所在内存的首地址。然后直接继承自这个基类的子类中会有它直接继承的父类的地址即Superclass,也就是这个基类的地址。也就是说每一个类都有一个Superclass指针指向它直接继承的父类(NSObject类或别的类),而每一个对象内部都有一个isa指针(指向直接创建这个对象的类),即由哪个类创建的这个对象那么这个对象内部的isa的值就是哪个类所占内存的首地址。(切记:如果这个类是根类例如NSObject,那么这个类的Superclass的值为NULL)。

注意:在首次用类创建对象时,切记是首次。即第一次用:[类名  alloc/new]来创建对象时会把这个类加载进内存。每个类只加载一次。即同一个类所创建的每个对象内部的isa指针都是相同的,都指向这个类。

6、在OC中,所谓的继承程单链继承,即单一继承。

7、id可以代替所有对象指针,id就是泛型。id在使用时也利用了动态绑定的原理。id在编译时是无法确定的,在将对象指针赋给id类型的变量后,利用id类型的变量调用方法时,id类型的变量会根据对象保存的isa指针(创建此对象的类的地址)来找到相应的方法列表进行调用。

8、OC中不允许子类和父类拥有相同名称的成员变量。但是方法可以相同(即重写:子类重新实现父类中的某个方法)。重写的好处是:覆盖父类以前的所有行为;

9、向上查找规则:当一个类的对象在调用方法的过程中,先从自身开始查找,如果自身的类中没有亲自实现的话就从父类中进行查找,如果父类中没有的话就一直向上查找。如果找到根类仍然没有的话就会报错。切记:优先查找自身的部分,没有的话再向上查找。这个过程是不可逆的。

10、在类的对象成员方法(实例方法)中不能用self来调用类方法(自身的不行,父类的更不行),同样类方法中也不能用self来调用实例方法(包括父类的)。概括为:类方法中只能调用类方法,对象方法中只能调用对象方法,在外部 类方法只能由类名调用,对象方法只能由对象调用。OC的特点就是界限很清楚,当用类名调用类方法时,或在类方法中用self调用了别的类方法,先从自身的类方法查找,如果有的话就直接调用  自身找不到时就从父类的静态方法中查找(还是向上查找的原则)。当用对象调用实例方法时也与此类似,不同的是当在自身的实例方法中找不到时,开始向上查找实例方法。

11、在同一个文件中如main.m 实现父类和子类的声明和实现时,必须将父类的声明写在子类声明的前面,与父类的实现和子类的实现的先后顺序无关。

12、继承的缺点:耦合性太强了,就是有继承关系的两个类之间联系过于紧密。当一个类出现变动/故障时,继承它的类也会崩溃。

13、继承常用的关键字super:

(1)super用来调用父类方法;当子类中重写了父类方法,如果想在这个子类方法中完全实现父类被重写方法的内容,就需要用super来调用被覆盖的父类版本的成员方法。(如果用self来调用这个方法,由于系统优先在自身查找的原因,等于是自己调用自己,会陷入死循环)。

(2)super不仅可以调用父类对象方法,也可以调用父类的类方法。但与self类似的是,子类对象方法中只能用super调用父类的对象方法。子类的类方法中只能用super调用父类的类方法。无论用哪种调用方式,对象方法中只能调用对象方法,类方法中只能调用类方法;无论哪种调用方式都遵循从自身开始向上查找的原则。

(3) 所以如果super在对象方法中就会调用父类的对象/实例方法,如果super在类方法中就会调用父类中的类方法。

注意:super的使用场合,一般当子类想在父类方法的基础之上做些延伸进而重写父类方法时需要把父类方法的实现内容拿过来,就要用super调用被覆盖的父类方法。

14、已知所有的OC类的初始化成员的方法有三个要点:(一)基本都是id类型,(二)必须返回self值,(三)必须调用父类的初始化方法来初始化从父类继承而来的成员。但是第三条具体实现可能有所不同,实现直接继承NSObject的类的构造方法中,直接用if(self=[super init]){  //初始化自身扩展的成员 }这是因为NSObject的初始化方法(构造方法)就是init。如果类不直接继承NSObject类,继承自手动实现的类,那么在实现它的构造方法 时就要用以下格式来初始化父类成员:if(self=[super 父类构造方法名:参数1,参数二,...参数n]){ //初始化自身扩展的成员 },除非这个手动提供的构造方法重写了NSObject的init方法,在继承这个手动类时才用第一种格式。

15、与C++类似的是在调用子类的dealloc方法时会自动调用父类的dealloc方法来释放子类从父类继承来的部分,所以不需要在子类的dealloc方法中调用父类的dealloc方法。这与组合类不同,组合类中的对象指针成员必须在类的dealloc方法中release一次。仍然遵循“ 谁创建,谁释放”的原则。

代码实现,实例如下:

代码要求
1、 定义一个轮胎类Tair,要求如下:a、实例变量:int screws; double radius;   b、实例方法:
初始化方法:要对两个变量进行初始化     输出方法:print用来输出所有实例变量的值    自己实现set方法:set方法包含两个形参         实现dealloc函数
2、 定义一个汽车类Car,要求如下:
c、 实例变量:int seats; double height; float width;Tair *tair;          d、实例方法: 初始化方法:要对四个变量进行初始化     输出方法:print用来输出所有实例变量的值
自己实现实例变量tair的set方法:set方法要求用retain模式。             实现dealloc函数
3、 定义一个轿车类SaloonCar,它继承于Car类。要求如下
a、 实例变量:int windows;    b、实例方法:
初始化方法:要对五个变量进行初始化
输出方法:print用来输出所有实例变量的值
实现dealloc函数

编辑Tair.h代码如下:

//
//  Tair.h
//  Test_extend
//
//  Created by apple on 15/8/15.
//  Copyright (c) 2015年 liu. All rights reserved.
//#import <Foundation/Foundation.h>@interface Tair : NSObject
{int screws;double radius;
}
@property int screws;
@property double radius;
-(id)setScrewAndRadius:(int) _screws andRadius:(double) _radius;
-(void) print;
@end

编辑Tair.m代码如下:

//
//  Tair.m
//  Test_extend
//
//  Created by apple on 15/8/15.
//  Copyright (c) 2015年 liu. All rights reserved.
//#import "Tair.h"@implementation Tair
@synthesize radius,screws;
-(id)setScrewAndRadius:(int) _screws andRadius:(double) _radius{if(self=[super init]){//super指向NSObject,调用了NSObject的init初始化构造方法self .screws=_screws;self.radius=_radius;}return  self;
}
-(void)print{NSLog(@"screws= %d   radius=%.2lf",self.screws,self.radius);
}
-(void)dealloc{NSLog(@"Invoke Tair Methods");[super dealloc];
}
@end

编辑Car.h如下:

//
//  Car.h
//  Test_extend
//
//  Created by apple on 15/8/15.
//  Copyright (c) 2015年 liu. All rights reserved.
//#import <Foundation/Foundation.h>
#import "Tair.h"
@class Tair;
@interface Car : NSObject
{int seats;double height;float width;Tair * tair;}
@property int seats;
@property double height;
@property float   width;
@property (nonatomic,retain) Tair * tair;
-(void) print;
-(id) initWithSeats:(int) _seats  andHeight:(double) _height andWidth:(float) _width andTair:(Tair *) _tair;
@end

编辑Car.m如下:

//
//  Car.m
//  Test_extend
//
//  Created by apple on 15/8/15.
//  Copyright (c) 2015年 liu. All rights reserved.
//#import "Car.h"
@implementation Car
@synthesize height,seats,width,tair;
-(void) print{NSLog(@"height=%.2lf width=%.2f seats=%d",self.height,self.width,self.seats);[tair print];
}
-(id) initWithSeats:(int) _seats  andHeight:(double) _height andWidth:(float) _width andTair:(Tair *) _tair{if(self=[super init]){self.seats=_seats;//利用self自身指针,调用了已经实现的setter方法进行赋值初始化self.height=_height;self.width=_width;self.tair=_tair;}return self;
}
-(void)dealloc{[tair release]; //释放自身扩展的成员,因为tair是类自身的成员部分。所以要由类自己的daealloc方法内进行释放,还是那句话“谁创建,谁释放”NSLog(@"Invoke Car");[super dealloc];//调用父类NSObject的dealloc方法,释放从父类继承来的部分
}
@end

编辑SalloonCar.h如下:

//
//  SaloonCar.h
//  Test_extend
//
//  Created by apple on 15/8/15.
//  Copyright (c) 2015年 liu. All rights reserved.
//#import <Foundation/Foundation.h>
#import "Car.h"
@class Car;
@interface SaloonCar : Car
{int windows;
}
-(id)initWithSeats:(int)_seats andHeight:(double)_height andWidth:(float)_width andTair:(Tair *)_tair andWin:(int) _windows;
-(void)print;
@end

编辑SalloonCar.m如下:

//
//  SaloonCar.m
//  Test_extend
//
//  Created by apple on 15/8/15.
//  Copyright (c) 2015年 liu. All rights reserved.
//#import "SaloonCar.h"
@implementation SaloonCar
-(id)initWithSeats:(int)_seats andHeight:(double)_height andWidth:(float)_width andTair:(Tair *)_tair andWin:(int) _windows{if (self=[super initWithSeats:_seats andHeight:_height andWidth:_width andTair:_tair]) {//调用父类(Car)初始化方法初始化从父类继承而来的成员windows=_windows;}return self;
}
-(void)print{//重写父类的方法,扩展父类。在父类实现的基础上增添新内容[super print];//利用super调用被覆盖的父类print方法NSLog(@"windows=%d",windows);//增添自己新特性
}
-(void)dealloc{//重写dealloc方法NSLog(@"SaloonCar Invoke");[super dealloc];//调用父类(Car)的dealloc方法,释放自身从父类继承来的部分
}
@end

编辑main.m如下:

//
//  main.m
//  Test_extend
//
//  Created by apple on 15/8/15.
//  Copyright (c) 2015年 liu. All rights reserved.
//#import <Foundation/Foundation.h>
#import "SaloonCar.h"
int main(int argc, const char * argv[])
{@autoreleasepool {Tair *t=[[Tair alloc] setScrewAndRadius:12 andRadius:35.4];[t print];Car *c=[[Car alloc] initWithSeats:100 andHeight:245.3 andWidth:23.3 andTair:t];[c setTair:t];[c print];SaloonCar *s=[[SaloonCar alloc]  initWithSeats:100 andHeight:251.23 andWidth:25.3 andTair:t andWin:600];[s print];[s release];[t release];[c release];}return 0;
}

运行结果如下:

OC继承详解与使用规则相关推荐

  1. C++继承详解之四——is-a接口继承和has-a实现继承

    在学习继承的过程中,不管是在书中还是在网上找资料,都跟多态分不开,其中还有个很抓人眼球的问题,那就是书上总是说的is-a关系和has-a关系. 很多书中讲到继承时都会说: public继承是一个接口继 ...

  2. python类继承中构造方法_第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解...

    第8.3节Python类的__init__方法深入剖析:构造方法与继承详解 一.    引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类没 ...

  3. (117)System Verilog类继承详解

    (117)System Verilog类继承详解 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog类继承详解 5)结语 1.2 FPGA ...

  4. firewall添加白名单_详解firewall的规则设置与命令(白名单设置)

    一. 设置firewall规则 例1:对外暴露8080端口 firewall-cmd --permanent --add-port=8080/tcp 例2:使mysql服务的3306端口只允许192. ...

  5. 【职坐标】java面向对象三大特性(二)——继承详解

    [职坐标]java面向对象三大特性(二)--继承详解 a) 什么是继承? i. 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可 b) ...

  6. C++继承和多态特性——继承详解(2)

    目录 一.派生类和基类的构造析构关系 1.派生类并不继承基类的构造和析构函数,只继承成员变量和普通成员方法 2.派生类的构造函数一定会调用基类的构造函数,析构也一样 3.为什么派生类的构造(析构)必须 ...

  7. JavaScript继承详解(四)

    文章截图 - 更好的排版 在本章中,我们将分析Douglas Crockford关于JavaScript继承的一个实现 - Classical Inheritance in JavaScript. C ...

  8. JavaScript继承详解(四) 转

    在本章中,我们将分析Douglas Crockford关于JavaScript继承的一个实现 - Classical Inheritance in JavaScript. Crockford是Java ...

  9. python3类的继承详解_python3中类的继承以及self和super的区别详解

    python中类的继承: 子类继承父类,及子类拥有了父类的 属性 和 方法. python中类的初始化都是__init__().所以父类和子类的初始化方式都是__init__(),但是如果子类初始化时 ...

最新文章

  1. nyoj 762:第k个互质数
  2. 目标检测发展路程(一)——Two stage
  3. PHP_框架储备资料
  4. MySQL常用函数之聚合函数
  5. zul ajax使用线程池
  6. 数据包络分析--综合的双目标数据包络分析模型
  7. Flotherm 2021热仿真分析基础到高级视频教程
  8. C#_HelloWorld 篇
  9. so反编译为c语言,SO文件反汇编实践
  10. b和kb的换算_b和bit换算(KB转换G)
  11. linux u盘 写保护,高手分享U盘被写保护的解决方案
  12. HTML的表单及框架
  13. DWT(离散小波变换)与其简单应用
  14. 童年的精彩(70年代~80年代初),以后的就不要看,会羡慕死你们的!^_^
  15. BZOJ1507 [NOI2003]Editor
  16. ImportError: libopencv_imgcodecs.so.4.3: cannot open shared object file: No such file or directory报错
  17. 周爱民先生力作《Delphi源代码分析》持续好评热卖中!!
  18. 项目开发流程(简述)
  19. Advanced Rails - Rails初始化20步
  20. (知乎)你是如何变的自律的

热门文章

  1. 为Linux草根队加油
  2. Linux 系统时间 EST 改 CTS
  3. linux网络测速qerf,kehu.one在线网速测试,网站测速工具,测网速,网站访问速度测试-boce.com...
  4. php实现登录验证码_PHP实现登录验证码功能
  5. pytorch安装(离线包)
  6. 阿里云云呼叫中心——软电话SDK前端接入
  7. EOS区块链常见错误编码代码汇总
  8. docker: Error response from daemon: Conflict. The container name “/mysql“ is already in use by conta
  9. row format delimited fields terminated by “,“含义是以‘,‘结尾的行格式分隔字段
  10. 【Java获取国家法定节假日三种工具类其二】