1. 遇到的问题.
多个类具有相同的成员.
a. 复制 粘贴.
-> 代码冗余.
-> 后期的维护不方便.
b.使用继承.
2. 继承的目的:
子类想拥有父亲类中的所有的成员.但是不想自己去定义,而是想凭空拥有.
如果发现另外1个类中的成员我也想有 那么这个时候就可以使用继承.
千万不要为了继承而去继承. 不要为了仅仅是得到某个类的成员就去随便继承.
满足继承的关系 is a
凡是满足is a关系的类 就可以拥有继承的关系.
当A类是1个B类的时候 那么A类就可以从B类继承
3. 继承的语法:
如何让1个类认另外1个类为爹 因为想拥有爹类中的所有的非真私有成员
语法:
@interface 类名 : 父亲类的名称
@end
继承是类在继承.而不是对象在继承.
子类从父类继承.子类中就拥有了父类中定义的所有非真私有的成员. 只是类继承.
我们创建对象. 对象与对象之间是毫无关系的.
实例变量修饰符
从写访问修饰符的地方开始往下.直到遇到另外1个访问修饰符或者结束大括弧为止。
中间的所有的属性都应用这个访问修饰符.
访问修饰符:访问修饰符只能用来修饰属性 不能用来修饰方法.
@public:任意程序集
@protected:该类和其派生类(子类) (如果声明时未做说明,那默认为是protected类型)
@private:该类 (@private类型的变量只能被继承但是不能访问,也就是说在子类中访问private类型的变量的时候,你只能看见提示有这个变量,但是上面有一道红线,表示无法被访问)
@package:框架级别的,作用域介于私有和公开之间,处于同一个框架之内就可以直接通过变量名访问
使用原则:
1). @public 无论什么情况下都不要使用. 属性不要直接暴露给外界.
2). @private 如果属性只想在本类中使用 不想在子类中使用 那么就使用它.
3). @protected: 如果你希望属性只在本类和本类的子类中使用.
推荐使用默认的@protected
OC中的私有变量
在类的实现中(也就是.m文件中),也是可以声明成员变量的,但是在.m文件中声明的成员变量是@private(“纯/绝对”私有变量,既不能被继承,也不能被访问),而且在.m文件中声明的成员变量不能和.h文件中的成员变量同名,在这期间,
即使是使用了@public等关键字修饰也是徒劳的。(也就是只能是@private类型的!!!)
无论在.m文件中的哪个位置定义一个新的变量,都是绝对私有变量,无法被其他类继承和访问
在.h文件中没有声明,但是在.m文件中实现的方法,叫做私有方法。私有方法无法被子类继承和访问。
绝对私有方法的访问
①我们利用self在.m文件中的其他可访问的方法下访问
②我们在.m文件中的其他可访问的方法下去实例化一个当前类的对象,然后用该对象调用这个私有方法(此时我们是在.m文件中实例化的这个对象,所以是可以访问真私有方法的)
在@implementaion之中也可以写1个大括弧.
把属性定义在@implementation的大括弧之中.
这里面的属性. 是1个私有属性. 各种访问修饰符无效.
外界根本就不会提示.
将属性定义在@implementation之中 和 将属性定义在@interface之中并标记为@private
唯一的区别: 提示和不提示. 都不能在外界访问.
4. 继承的效果:
儿子类一旦从父亲类去继承.那么儿子类中拥有了父亲类中的所有的成员. 不用自己定义.
子类从父类继承,就意味着子类拥有了父类的所有的成员 包括属性 方法.
子类仍然可以继承父类的私有属性.
只不过,在子类中无法去直接访问从父类继承过来的私有属性.
但是如果父类中有1个方法再为属性赋值或者取值.
那么子类可以调用这个方法间接的访问父类的私有属性.
5. 几个术语:
NSObject类.
是Foundation框架中的类.在这个类中有1个类方法new
这个方法是用来创建对象的.方法的返回值是创建的这个对象的指针.
也就是说,如果要创建类的对象,就必须要调用这个new方法.
如果我们想要让我们的类具备创建对象的能力,就必须要让我们的类直接的或者间接的从NSObject类继承.
所以.要求: 我们写的类必须直接的或者间接的要NSObject类继承.
如果你不继承,我们的类就无法创建对象. 那么我们的类就毫无意义.
在NSObject类之中 还定义了1个属性. 这个属性叫做isa指针.
所以,每1个子类对象中都有1个叫做isa的指针.
NSObject类是OC中所有类的祖宗类. 因为OC中的类全部都是直接的或者间接的从它继承,
@interface Student : Person
1). Student类从Person类继承. Studdent类是Person类的子类 Person类是Student的父类.
2). Student类从Person类派生. Student类是Person类的派生类.Person类是Student类的基类.
子类一旦从父类继承 就意味着子类拥有了父类的所有的成员 而不用自己去定义.
如果有1个成员不是所有的子类都拥有的.那么这个成员就不应该定义在父类之中.
因为一旦定义在父类之中.那么所有的子类全都有了.
父类中只定义所有的子类都拥有的.只要不是所有的子类都拥有的 那么就不应该定义在父类之中.
重写:
在父类中有的方法,但是在子类中又重新定义了一下,这就叫做方法的重写。重写可以不写方法的声明。
就近原则:
在类的实例对象调用方法的时候,先查看自己本类中有没有该方法,如果该类中有,就先调用自己的,如果没有就去其父类中寻找,如果父类中再没有,那么再往上一层去寻找,找到后就执行,但是如果到NSObject中还没有的话就报错了。这里可以看成是就近原则。
在NSObject类中我们打开之后发现里面有这么一句话,这个东西虽然暂时看是一个对象,但是里面解开之后底层是一个名为description的对象方法。用作输出对象的信息。我们还可以在.m文件中对这个方法进行重写。可以看成是一个description的get方法,因为这个方法就是返回一个NSString类型的值
NSLog(@"%@",person);//<Person: 0x100206790>
这里用%@格式打印出来的是这样一个字符串,显然里面的一些数字表示的person对象的地址,与上面我们打印的地址是一样的。这里其实是打印的person对象的信息,而这里调用了一个description方法,这个方法是一个对象方法,其格式是这样子的。每当我们用%@的格式打印对象,都会出现这样的信息。但是我们在Dog类中并没有写description这个方法啊?答案就是这个方法存在于NSObject类中。
super关键字.
1). 可以用在类方法和对象方法之中.
2). 在对象方法中可以使用super关键字调用当前对象从父类继承过来的对象方法.
3). 在类方法中 super关键字可以调用当前类从父类继承过来的类方法.
a. 类方法也能被子类继承. 父类中的类方法可以使用父类名来调用 也可以使用子类名调用.
b. 在子类的类方法中 可以使用super关键字调用父类的类方法.
4). super只能用来调用父类的对象方法或者类方法 不能用来访问属性.
子类从父类继承.
1). 相当于子类模板中拥有了父类模板中的所有的成员(非真私成员).
2). 创建1个子类对象,仍然是根据子类模板来创建对象.
只不过子类模板中拥有父类模板中的成员.
所以,子类对象中既有子类的成员也有父类的成员.
3). super特指这个方法是从父类继承过来的.
super是指当前类或者对象的这个方法是从父类继承过来的.
6.总结
派生类方法属性=基类方法和属性+派生类自己新增的方法和属性
基类的私有属性能被继承,但是不能访问(@private类型的变量是能够被继承的,但是不允许访问。可显示变量名说明能继承,访问在提示的时候是会有红色线标记说明无法访问)
OC中的继承是 单继承 的,也就是说一个类只能有一个父类,不能继承多个父类
子类不能定义和父类同名的变量,但是可以继承父类的变量
OC类支持多层继承 A类从B类继承,B类从C类继承. 那么A类就同时拥有B、C类的成员. 动物类:Animal ——> 狗类:Dog ——> 军犬类:JunQuan
在.m文件中声明成员变量不能和.h文件中的成员变量同名。
在.m文件中声明的成员变量只能是@private类型的。