黑马程序员--OC自学笔记--04self、super、继承、多态、修饰符

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


 

1.   self和super

1)        OC中的self,相当于C++、java中的this指针

2)        super用来调用父类的方法

2.   self用在对象方法中

self指代的是调用当前方法的对象

3.   self用在类方法中

[对象 class];返回的实质就是当前类(类对象)

self指代的是当前类,不能调用对象方法。

4.   self修饰变量

1)        函数内部定义和全局变量同名的变量,则局部变量会屏蔽全局变量的作用域。

2)        self修饰变量来访问实例变量,不加self访问的是局部变量。self->_name;

5.   类的继承和派生

1)        基类的私有属性不能被访问

2)        OC中的继承是单继承

6.   方法的重写

1)        把父类已经实现的方法在子类中重新实现一遍,称为对父类方法的重写。

2)        不用再在子类中声明,只要实现就行

7.   继承的注意事项

1)        子类不能定义和父类同名的变量,但是可以继承父类的变量

2)        OC中只支持单继承

3)        OC中支持多层继承

4)        继承体系中方法的调用顺序:本类—>父类—>父父类—>….-->NSObject

8.   实例变量的修饰符

1)        public           所有类都可以访问

2)        protected            只能在当前类和子类中被访问

3)        private          只有当前类可以访问

4)        在@interface和@end之间声明的变量默认是@protected

5)        一个类继承了另一个类,那么就拥有了父类的所有成员变量和方法,注意所有的成员变量它都拥有,只是有的不能直接访问

6)        面试题:

①  子类是否可以继承父类中被@private修饰的实例变量

可以,子类可以继承父类的所有实例变量和方法

②  子类是否可以访问父类中被@private修饰的实例变量

子类不能访问父类中被@private修饰的实例变量和方法

9.   OC中的私有变量

1)        在.m文件中定义的成员变量是纯私有的,只能在当前类中使用,不能被其他类继承和访问

10. OC中的私有方法

1)        在.h中没有声明,在.m中实现的方法为私有方法。

2)        .h文件对外相当于一个接口,声明了哪些东西,其他文件就可以使用哪些东西,没声明的不能用。

3)        私有方法不能被继承

11. description方法

1)        当我们以%@的格式,打印对象时,此时调用对象的description方法

2)        如果当前对象中没有重写description方法,则调用父类的description方法,也就是说打印出对象的地址。

3)         重写description方法时,如果调用了self,会造成死循环。

12. 多态

1)        概念:不同的对象以自己的方式响应相同名称方法的能力称为多态。

2)        多态的条件:

①  有继承关系、有方法重写。

②  父类的声明变量指向子类对象。

3)        多态的优点:

①  简化了编程接口,允许在类和类之间重用一些习惯性的命名,而不用为每一个新加的函数命名一个新名字。

②  多态使得代码可以分散在不同的对象中,而不用试图在一个函数中考虑到所有可能的对象。

4)        多态的原理和实现:

①  动态绑定:动态类型能使程序直到执行时才确定对向所属类型

②  动态类型绑定能使程序直到执行时才确定要对对象调用的实际方法

③  OC不同于传统程序设计语言,它可以在运行时加入新的数据类型和新的程序模块:动态类型识别,动态绑定,动态加载

④  Id类型:通用指针类型,弱类型,编译时不进行类型检查。

#import <Foundation/Foundation.h>
@interface Animal : NSObject
-(void)run;
@end
 
#import "Animal.h"
@implementation Animal
-(void)run{
    NSLog(@"动物在跑");
}
@end
 
#import "Animal.h"
@interface Dog : Animal
-(void)eat;
@end
 
#import "Dog.h"
@implementation Dog
-(void)run{
    NSLog(@"狗在跑");
}
-(void)eat{
    NSLog(@"狗在吃东西");
}
@end
 
#import "Dog.h"
@interface BigYellowDog : Dog
 
@end
 
#import "BigYellowDog.h"
@implementation BigYellowDog
-(void)run{
    NSLog(@"大黄狗在跑");
}
@end
 
#import <Foundation/Foundation.h>
#import "BigYellowDog.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //多态1
        //父类指针指向子类对象,可以调用子类的同名方法
        Animal *an1 = [Dognew];
        [an1 run];
       
        //多态2
        //父类指针指向子子类对象,可以调用子子类的同名方法
        Animal *an2 =[BigYellowDog new];
        [an2 run];
       
        //多态3
        Animal *an3 = [Dognew];
        //[an3 eat];      //父类不能调用子类的新增方法
        [(Dog *)an3 eat]; //可以通过强转为子类类型来调用子类
新增的方法
      
        //非多态
        //Animal *an4 =[Animal new];
        //[an4 eat];
        //[(Dog *)an4 eat];//不具有多态关系,即使强转为子类
类型也无法运行,能够让编译器误认为是可以的,所以可以通过编译
,但是运行时出错。
       
    }
    return 0;
}

13. 类的本质

1)        类的本质其实也是一个对象(类对象)

2)        类对象:

①  类对象在程序运行时一直存在

②  类对象是一种数据结构,存储类的基本信息

③  类对象所保存的信息在程序编译时确定,在第一次使用该类的时候被加载到内存中。

④  类对象代表类,class代表类对象,类方法属于类对象。

⑤  如果消息的接收者是类名,则类名代表类对象

⑥  运行时,所有类的实例都由类对象生成,类对象会把实例的isa的值修改成自己的地址,每个实例的isa都指向该实例的类对象

⑦  从类对象那里可以知道父类信息、可以响应的方法等

⑧  类对象只能使用类方法,不能用实例方法

3)        我们所定义的类其实也是一个对象,比如Person *p = [Person new];

Person是一个对象,是Class类型的

4)        类对象的获取

①  通过实例对象获取

Person *p = [Person new];

Class c1 = [p class];

这是通过实例对象p的class方法来得到类对象。

②  通过类名获取

Person *p = [Person new];

Class c2 = [Person class];

这是通过类名Person来得到类对象,这里的c1=c2

14. SEL类型全称为selector,表示方法的存储位置

Person *p = [Person new];

[P test];

寻找方法的过程:

1)        首先把test这个方法名包装成SEL类型的数据;

2)        根据SEL数据找到对应的方法地址

3)        根据方法地址调用相应的方法

4)        注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用

注意:SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址。

调用方法:

Person *p = [Person new];

//手动把test方法包装成SEL类型

SEL s = @selector(test);

//响应方法

[p performSelector:s];

这两行就相当于[p test];

15. 类对象的存储 细节


对象的实例变量p存放的是堆区中实例对象的地址,然后会找到其中的isa指针,实例对象的isa指针指向堆中的Person类对象的地址,类对象中包含所要找的方法的SEL类型,根据类对象的中isa指针指向代码区的地址,在代码区中找对应的SEL类型就是要调用的方法。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌影~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值