OC基础day05
继承的简单使用
- 代码中的继承是什么意思?
- 继承是一个创建类的方式,当想要创建一个B类,但是不想写B中的成员,发现A中有自己想要的成员,这个时候就可以用继承关系 把A类中的所有成员继承过来
- 几个名词
- 类B的继承自类A B类叫做A类的子类/派生类
- A类叫做B类的父类/基类
-
继承是类在继承问不是对象在继承
- 继承是类在继承而不是对象在继承
- 父类对象与子类对象是毫无关系的
-
什么时候使用继承
- 当发现A类中的成员 B类也想有 就让B类继承A类
- 继承需要合理性
- 必须满足 is a 关系的两个类才能继承
- 比如 狗类 可以继承 动物
- 只要成员不是所有子类都拥有的就不应该定义在父类中
-
OC继承的特点
- 用继承方式创建类的有什么特点?
- 单根性/单继承性,OC中一个类只能有一个父类
- 传递性, C类继承自B类, B类继承自A类 那么C类拥有A的所有属性方法(即子类拥有父类和父类的父类的所有属性和方法)
- 用继承方式创建类的有什么特点?
NSObject类
- **NSObject是什么?
- 是一个类 是所有类的根类
- 为什么要继承NSObject
- 因为所有的类需要创建对象 需要一个new来创建对象 new方法就是在NSObject中定义的
- 还有 new dealloc description… 都在NSObject类中
super 关键字
- 在子类的对象方法中需要调用从父类继承过来的对象方法
- [self 方法名]
- [super 方法名]; 显示告诉程序员这个方法是从父类继承过来的
- 在类方法中使用 super关键字
- 在子类的类方法中需要调用从父类继承过来的类方法
- [子类名 类方法名];
- [父类名 类方法名];
- [self 类方法名];
- [super 类方法名]; 显示告诉程序员是从父类继承过来的类方法
- 所以以后早子类中 需要调用从父类继承过来的方法 就要用 super 更为简单 易懂
- super关键字 不能访问属性 只能调用方法
* 属性的访问修饰符*
- 是什么
- @public 公共的
- @protected 受保护的 默认的
- @private 私有的
- @pachage 框架级别
- 有什么用
- 在类的.h 文件中的属性声明 用着四中关键字声明 可以限制属性在当前类和子类中的访问权限
分别有什么用
- 无论是什么属性的修饰符都会被子类继承
- 内部: 就是在当前类的方法中
- 外部: 就是在main函数中通富哦该类的对象访问
- 修饰符的权限从大到小
- @public > @package > @protected > @private
- @public
- 在所有的程序中都能访问
- @protected
- 在本类的内部可以直接访问,外部不能直接访问
- 在子类的内部可以直接访问,外部不能直接访问
- @private
- 在本类的内部可以直接访问,外部不能
- 在子类的内部不能直接访问, 外部不能
- 访问修饰符的作用于
- 从定义修饰符开始到下一个出现或者大括号结束
私有属性和真私有放大的应用
- 真私有属性
- 在@private修饰的属性 私有属性
- 写在.m的@implementation大括号中的属性 真私有属性
- 私有属性和真私有属性唯一的区别 Xcode不会提示
- 建议使用:
- 以后写一个类 一把会有两种属性
- 一种在.h中用@protected修饰的属性
- 一种在.m中的真私有属性
- 私有方法
- 只在 .m中实现 不在.h中声明
里氏替换原则 (缩写 LSP)
- 一句话
- 父类的指针 可以指向子类的对象
-
里氏替换原则的好处
举例:
人类
属性:名字
行为:喂狗,喂猫,喂猪(在实现中打印"xxx正在吃shi")
狗类,猫类,猪类
属性:姓名在main函数中 实现人喂猪,喂狗,喂猫的过程
-
里氏替换原则的局限性
- 父类的指针 可以指向子类的对象
- 父类的指针 只能访问子类从父类继承过来的属性和方法
- 不能访问子类独有的成员
方法重写
- 什么叫方法重写
- 子类中重新实现父类继承过来的方法
- 什么时候需要方法重写
- 父类继承过来的方法 子类完全不适用 重写方法
- 父类继承过来的方法 子类需要补充 也需要方法重写,
- 但是重写方法的时候 要使用super关键字 [super 方法名]
- 先调用父类的方法 然后在添加自己想要的实现
- 如何重写?
- 在 .m文件中 重新实现要重写的方法 不是改声明 也不需要再次声明
强调
如果一个父类指针,指向了子类对象
如果通过父类的指针调用子类重写的方法
那么调用的是子类重写后的方法
多态
- 多态 不同的事物 同一种行为 不同的表现形式
- 一个多态满足3各条件
- 有继承关系
- 有方法重写
- 有父类的指针 指向子类的对象
- 一个多态满足3各条件
description 方法
- %@打印对象的原理
- 使用%@打印对象时, 内部的原理
- NSLog(@”%@”,对象名);
- 调用 [对象名 description]; 返回一个字符串
- 把这返回的字符串打印到控制台
- 如果想要自定义打印出对象的格式 那么需要重新这个description方法
* 继承的本质*
- 子类会继承所有的属性的方法
- 子类创建对象的时候 会在堆区中开辟 只会开辟属性所占的空间
- 子类调用方法时, 方法的查找顺序
- Student *stu = [Student new];
- [stu dercription];
- 首先会在本类中寻找 如果有直接调用
- 如果没有 回想它直接父类中寻找 如果有直接调用
- 如果没有 回继续想上一级父类中寻找 如果还是没有
- 会一直找,直到NSObject这个类 如果这个类还是没有就报错
类是一Class对象的形式存储在代码中的
@interface Person : NSObject
{
NSString *_name;
}
+ (void)sss;
- (void)sayHi;
@end
- 一个类在内存中是一Class对象的形式存储的
- 那么这个Class对象就是带表这个类
- 如何获取存储这个类的Class对象
- 通过[对象名 class] 可以获取到Class对象
- 通过[类名 class]可以获取到这个Class对象
- Class对象 存储了类的所有信息
- 也就是说Class对象 就代表了这个类
- Class cc = [Person class];
所以
- 使用Class对象调用类方法 [cc sss] 就可以直接调用类方法
- 使用Class对象 创建Pweson对象[cc new];
- 类的本质 就是一个对象 Class类型的对象
SEL数据
- 每一个类都有方法 其实方法在内存中也是以一种形式存在的
- 一个方法在内存中 是以 SEL这种数据类型存在的
//定义一个变量 来存储一个方法 sayHi
SEL sayHiSel;//这是一个变量,这变量可以存储方法
//@selector(方法名) 功能:根据一个方法名 返回一个SEL对象
sayHiSel = @selector(sayHi);