复习:
1. Xcode文档的安装与使用.
2. static关键字修饰方法中的局部变量.
3. self关键字.
1). 在对象方法中.
父类的成员对于子类来讲,也是属于子类的.所以父类的成员在子类的方法中也可以使用self
2). 在类方法中.
4. 继承.
1). 继承的目的:
2). 继承的语法:
3). 继承的效果:
4). 继承是类在继承而不是对象在继承.
5). 满足继承的关系.
is a
6). 继承的特点.
7). NSObject类.
8). 访问修饰符.
5. 私有属性和私有方法.
6. 里氏替换原则.
1).什么是LSP
Person *p1 = [Student new];
2).为什么LSP是可以的.
3).LSP的表现形式. 父类指针指向子类对象.
4).LSP的好处.
5).当1个父类指针指向1个子类对象的时候.只能通过这个父类指针访问这个对象中的父类成员.
7. 方法重写
1). 什么时候需要方法重写?
2). 如何重写
3). LSP的时候 通过指针调用的方法被子类重写了 那么调用的是子类重写的.
8. 多态.
02-继承的本质
1. 创建1个对象,这个对象在内存中是如何分配的.
1). 子类对象中有自己的属性和所有父类的属性.
2). 代码段中的每1个类都有1个叫做isa的指针,这个指针指向它的父类.
一直指到NSObject
[p1 sayHi]; //假设p1是Person对象.
先根据p1指针找到p1指向的对象,然后根据对象的isa指针找到Person类.
搜索Person类中是否有这个sayHi方法 如果有执行
如果没有 就根据类的isa指针找父类 。。。。。
NSObject 中如果没有就报错.
03-作业
1.人类
姓名 性别 年龄.
2.书类
书名 作者 出版社 出版日期.
3.学生类
姓名 性别 年龄 学号 书.
读书
日期: 年 月 日.
------------------------------------------------
1. 结构体与类的相同点
都可以将多个数据封装为1个整体.
struct Date
{
int year;
int month;
int day;
};
@interface Date : NSObject
{
int year;
int month;
int day;
}
@end
2. 结构体与类的不同点
1). 结构体只能封装数据,而类不仅可以封装数据还可以封装行为.
2). 结构体变量分配在栈空间 (如果是1个局部变量的情况下)
而对象分配在堆空间.
栈的特点: 空间相对较小. 但是存储在栈中的数据访问的效率更高一些.
堆的特点: 空间相对较大. 但是存储在堆中的数据访问的效率相对要低
存储在栈中的数据访问效率高 存储在堆中的数据访问效率低.
3). 赋值.
结构体 Student
类: Person
Student s1 = {"jack",19,GenderMale};
Student s2 = s1;
Person *p1 = [Person new];
Person *p2 = p1;
3. 应用场景.
1). 如果表示的这个实体 不仅是由多个数据组成, 这个是实体还有行为,只能使用类.
2). 如果表示的实体没有行为.光有属性.
a. 如果属性较少.只有几个. 那么这个时候就定义为结构体 分配在栈 提高效率.
b. 如果属性较多.不要定义成结构体. 因为这样结构体变量会在栈中占据很大1块空间
反而会影响效率.
定义为类.
04-类的本质
1. 内存中的五大区域.
栈
堆
BSS段
数据段
代码段.
代码段:是用来存储代码的.
类加载. 当类第1次被访问的时候 这个类就会被加载到代码段存储起来.
2. 讨论三个问题
1). 类什么时候加载到代码段.
类第1次被访问的时候,类就会被加载到代码段存储 类加载.
2). 类以什么样的形式存储在代码段.
3). 类一旦被加载到代码段之后 什么时候回收.
是不会被回收的 除非程序结束.
3. 类是以什么样的形式存储在代码段的.
1). 任何存储在内存中的数据都有1个数据类型.
int num = 12;
float 12.12f
'a'
任何在内存中申请的空间也有自己的类型.
Person *p1 = [Person new];
2). 在代码段存储类的那块空间是个什么类型的.
在代码段中存储类的步骤
a. 先在代码段中创建1个Class对象, Class是Foundation框架中的1个类.
这个Class对象就是用来存储类信息的.
b. 将类的信息存储在这个Class对象之中.
这个Class对象.至少有3个属性
类名: 存储的这个类的名称.
属性s: 存储的这个类具有哪些属性
方法s: 存储的这个类具有哪些方法.
所以.类是以Class对象的形式存储在代码段的.
存储类的这个Class对象 我们也叫做类对象. 用来存储类的1个对象.
所以,存储类的类对象也有1个叫做isa指针的属性 这个指针指向存储父类的类对象.
4. 如何拿到存储在代码段中的类对象.
1). 调用类的类方法 class 就可以得到存储类的类对象的地址.
2). 调用对象的对象方法 class 就可以得到存储这个对象所属的类的Class对象的地址.
3). 对象中的isa指针的值其实就是代码段中存储类的类对象的地址.
注意:
声明Class指针的时候 不需要加* 因为在typedef的时候已经加了*了.
5. 如何使用类对象.
1). 拿到存储类的类对象以后.
Class c1 = [Person class];
c1对象就是Person类.
c1 完全等价于 Person
2). 使用类对象来调用类的类方法.
因为类对象就代表存储在这个类对象中类.
Class c1 = [Person class];
c1就代表Person类.
所以在使用Person的地方完全可以使用c1代替.
比如我们使用类名来调用类方法.
[Person sayHi];
完全可以使用c1来调用. 因为c1就是Person
[c1 sayHi];
3). 可以使用类对象来调用new方法 创建存储在类对象中的类的对象.
Person *p1 = [Person new];
Class c1 = [Person class];
其实创建Person对象 也可以这么做.
Person *p2 = [c1 new];
4).注意:
使用类对象 只能调用类的类方法,因为类对象就等价于存在其中的类.
Class c1 = [Person class];
c1就是Pers