是什么?
类的本质还是对象,叫类对象.用Class表示
类的底层:typedef struct obj_class*Class(结构体)
有什么用?
场景:想让程序一起的就给某值赋值!(load)
场景:创建对象的时候,给某属性赋值,且只是赋值一次(initialize)
场景:创建对象的时候,给属性赋值,且每次创建都进行赋值(init)
怎么用?
获取类(类对象)的方法:
Class c = [类名 class];
Class c = [对象名 class];
类对象加载会调用load方法
对象加载会initialize
+(void)initialize{}
+(void)load{}
-(id)init{}
用的时候需要注意什么? 1) 类对象创建的时候不用加*, Class c = an.clas
对象创建的时候要加*,Animal * an =[[Animal alloc]init
2)一个类(类对象)可以有多个对象(对象的地址和值都不同),但是类(类对象的地址不同,值相同)只有一个!
分析:
类在创建类的对象时,每次创建,它就会开辟一个新的空间,里面会有isa指针,每一个isa指针都指向同个类对象,(所以,对象可以有多个,但类对象只有一个)
3)对象是在创建对象的时候加载,类(类对象)是在程序启动的时候就加载! 4)一个类的对象被创建,则其父类的对象也会被创建,父类的父类也会被创建...
5)分类中创建本类相同名称的方法,会覆盖本类的方法!load方法特殊!
- //
- // Animal.h
- //
- #import <Foundation/Foundation.h>
- @interface Animal : NSObject
- @end
- //
- // Animal.m
- //
- #import "Animal.h"
- @implementation Animal
- /*
- 当类对象加载,会调用load方法
- 验证,写个空的main方法,运行时会打印出
- 下面这句话...
- */
- +(void)load{
- NSLog(@"Animal类对象加载的方法load...");
- }
- /*
- 对象创建时,会调用的方法initialize
- 不管有创建了多少对象,只会加载时调用一次,并且是在load方法之后调用!
- 验证:
- main中创建多个对象,只会打印一次语句
- */
- +(void)initialize{
- NSLog(@"Animal对象加载的方法initialize...");
- }
- /*
- 对象每次创建的时候,就会调用一次init方法
- 验证:
- main中创建对象,创建几次,就会打印几次
- */
- - (instancetype)init
- {
- self = [super init];
- if (self) {
- NSLog(@"Animal对象加载的方法init...");
- }
- return self;
- }
- @end
- //
- // Cat.h
- //
- #import "Animal.h"
- @interface Cat : Animal
- @end
- //
- // Cat.m
- //
- //
- #import "Cat.h"
- @implementation Cat
- +(void)load{
- NSLog(@"Cat类加载的方法load...");
- }
- + (void)initialize
- {
- NSLog(@"Cat类的对象加载方法initialize...");
- }
- -(id)init{
- self = [super init];
- if (self) {
- NSLog(@"Cat的对象加载方法init...");
- }
- return self;
- }
- @end
- //
- // BsCat.h
- //
- #import "Cat.h"
- @interface BsCat : Cat
- @end
- //
- // BsCat.m
- //
- #import "BsCat.h"
- @implementation BsCat
- +(void)load{
- NSLog(@"BsCat类加载的方法load...");
- }
- + (void)initialize
- {
- NSLog(@"BsCat类的对象加载方法initialize...");
- }
- -(id)init{
- self = [super init];
- if (self) {
- NSLog(@"BsCat的对象加载方法init...");
- }
- return self;
- }
- @end
- //
- // Animal+sport.h
- //
- #import "Animal.h"
- @interface Animal (sport)
- @end
- //
- // Animal+sport.m
- //
- /*
- 一般
- 分类中的方法和本类的方法相同,则最后一次的方法,将覆盖前面一次的方法!
- 特殊
- 分类中的load方法,不会覆盖本类的load方法
- 分类中子类的load方法,同样不会覆盖父类和本类的load方法
- */
- #import "Animal+sport.h"
- @implementation Animal (sport)
- +(void)load{
- NSLog(@"Animal (sport)类加载的方法load...");
- }
- + (void)initialize
- {
- NSLog(@"Animal (sport)类的对象加载方法initialize...");
- }
- -(id)init{
- self = [super init];
- if (self) {
- NSLog(@"Animal (sport)的对象加载方法init...");
- }
- return self;
- }
- @end
- //
- // Cat+eat.h
- //
- #import "Cat.h"
- @interface Cat (eat)
- @end
- //
- // Cat+eat.m
- //
- #import "Cat+eat.h"
- @implementation Cat (eat)
- +(void)load{
- NSLog(@"Cat (eat)类加载的方法load...");
- }
- + (void)initialize
- {
- NSLog(@"Cat (eat)类的对象加载方法initialize...");
- }
- -(id)init{
- self = [super init];
- if (self) {
- NSLog(@"Cat (eat)类的对象加载方法init...");
- }
- return self;
- }
- @end
- /*
- main.m
- 类本质上还是一个对象.叫类对象.这个对象的类型:Class
- 类对象是在程序启动的时候加载的,与对象创建无关.
- 类对象加载的标志:是load方法.
-
- 对象是在它被创建的时候加载的.且必须在类对象加载完成后才会加载.
- 对象加载会执行initialize方法. 只会在对象第一次创建的时候执行.
-
- 类,类对象,对象
- //Animal 是类对象! an是Animal的对象!c是类!
- Animal * an =[[Animal alloc]init];
- Class c = an.class;
-
- 方法:load/initialize/init
- load 是类(类对象)的加载方法
- initialize 是对象的加载方法(对象创建的时候执行,只执行一次)
- init 是构造方法(对象创建的时候执行,每次都执行)
- 注意:
- 1)对象在创建时,只会在第一次创建的时候加载一次,后面就不会加载了!
- 2)一个类(类对象)可以有多个对象,但是类(类对象)只有一个!
- 3)类对象在创建的时候不用加*,对象在创建的时候要加*.
- 4)一个类的对象被创建的时候,它父类的对象也会被创建,它父类的父类的对象也会被创建(间接父类也会被创建)
- 特殊:
- 一般
- 分类中的方法和本类的方法相同,则最后一次的方法,将覆盖前面一次的方法!
- 特殊
- 分类中的load方法,不会覆盖本类的load方法
- 分类中子类的load方法,同样不会覆盖父类和本类的load方法
-
- */
- #import <Foundation/Foundation.h>
- #import "Animal.h"
- #import "Cat.h"
- #import "BsCat.h"
- int main(int argc, const char * argv[]) {
- //
- // //Animal 是类对象! an是Animal的对象!
- // //类对象在创建的时候不用加*,对象在创建的时候要加*.
- // Animal * an =[[Animal alloc]init];
- // Class c = an.class; //c是类
- //
- // //对象可以有多个,且每个都是独立得(地址和值都不同)
- // Animal * an1 =[[Animal alloc]init];
- // Animal * an2 =[[Animal alloc]init];
- // Animal * an3 =[[Animal alloc]init];
- // //对象的每个地址和值,都不同!
- // NSLog(@"an1的地址=%p,an2的地址=%p,an3的地址=%p",&an1,&an2,&an3);
- // NSLog(@"an1的值=%p,an2的值=%p,an3的值=%p",an1,an2,an3);
- //
- //
- // //&c1 是指针c的地址! c1是指针存放的值!
- // Class c1 = [an class];
- // NSLog(@"c1的地址=%p,c1的值=%p",&c1,c1);
- //
- // //类对象只能有一个(类的值相同)
- // Class c2 = [an2 class];
- // Class c3 = [an3 class];
- // Class c4 = [Animal class];
- // //类的地址不同K
- // NSLog(@"c的地址=%p,c2的地址=%p,c3的地址=%p,c4的地址=%p",&c,&c2,&c3,&c4);
- // //类的值相同
- // NSLog(@"c的值=%p,c2的值=%p,c3的值=%p,c4的值=%p",c,c2,c3,c4);
- //
- //创建多个对象,但是加载方法(initialize)只调用一次,(init)方法每次都执行
- // Animal *am = [[Animal alloc]init];
- // Animal *am2 = [[Animal alloc]init];
- // Animal *am3 = [[Animal alloc]init];
- // Animal *am4 = [[Animal alloc]init];
-
-
- //这并没有创建子类Cat类的对象,因为它是父类Animal的对象
- //所以,再次加载了Animal类的对象init方法!
- //但,加载了Cat类的load方法,因为load方法跟创建没有关系!只要出现了,程序启动就会加载load方法!
- //Cat *ct = [[Animal alloc]init];
-
- //子类对象被创建,它父类对象也会被创建(加载了父类的init方法)
- //Cat *ca = [[Cat alloc]init];
-
- //子类对象被创建,它父类对象也会被创建(加载了父类的init方法),它的父类的父类的对象也被创建
- //每次创建对象,都会加载父类/父类的父类/子类的间接父类的(init)
- // BsCat *bc = [[BsCat alloc]init];
- // BsCat *bc2 = [[BsCat alloc]init];
-
- // Animal *al =[[Animal alloc]init];
- // Animal *al2 =[[Animal alloc]init];
-
- Cat *ct = [[Cat alloc]init];
-
-
- return 0;
- }
复制代码
|