A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始



第五天
一. 多态
1. 多态概念,定义
什么是多态:
    多态就是某一类事物的多种形态;

官方一点说:
    多态就是,不同的对象以自己的方式响应父类同名的方法,这就是多态;

代码中体现出来:
    父类的指针指向了子类的对象;Animal *ani = [Dog new];

多态条件:
    1.有继承关系
    2.有方法的重写


2.多态代码实现:
//实例化猫的对象
Animal *animal  = [Cat new]; //父类的指针指向子类对象;
[animal eat];

//实例化狗的对象
animal = [Dog new]; //父类的指针指向子类对象。
[animal eat];



3.多态注意点:
1) 如果存在多态,父类是可以访问子类特有的方法
假设子类Dog 有一个特有的方法bark
Animal *an2 = [Dog new];         //编译时看等号左边,运行时看等号右边
[(Dog*)an2 bark]; //把父类的指针,强制类型转换

2) 如果不存在多态,父类是不可以访问子类特有的方法的
Animal *an3 = [Animal new];
[(Dog*)an3 bark]; //错误的,这里只是骗编译器,运行一定报错.



二.类对象
1,类的本质其实也是一个对象(类对象,Class类型);

类对象
    *类对象在程序运行时一直存在。
    *类对象是一种数据结构,存储类的基本信息:类大小,类名称,类的版本以及消息与函数的映射表等
    *每一个对象都包含一个指向其类对象的isa指针。


2、类对象如何获取
通过实例对象获取
Dog *d1 = [Dog new];
Dog *d2 = [Dog new];
Class c =   [d1 class];
Class c2 = [d2 class];

通过类名获取(类名其实就是类对象)
Class c3 = [ Dog  class ];

因为类对象在整个程序中只存在一份,
所以 c = c2 = c3


3.类对象的使用
1)可以用来调用类方法:
//获取类对象
Class c1 = [Person class];
//使用类对象调用类方法
[c1 test]; // test是一个+号方法

2)可以用来实例化实例对象, 并且调用对象方法
//获取类对象
Class c1 = [Person class];
//使用类对象创建实例对象
Person *p = [c1 new];
[p test];  // -test 调用对象方法

4. 类对象存储细节
通过打印地址分析测试:类对象存在常量区;

5.SEL类型 (@selector()选择器)
就是对方法的一种包装,将方法包装成SEL类型;
包装后 函数可以当参数传递

SEL是一种新的数据类型。和id、class一样。
Person *p = [Person new];
SEL s1 = @selector(test);
[p performSelector:s1];



三. 点语法
1. 传统setter, getter方法
-(void)setAge:(int)age{
    _age = age;
}

-(int)age{
    return _age;
}

2. 点语法
本质上展开之后相当于调用setter, getter方法
p.age = 10;  展开之后等价于   [p setAge:10];  // setter方法

NSString *name = p.age; 等价于NSString *name = [p name]; // getter方法

对象. 成员变量  展开之后到底是setter方法, 还是getter方法, 看在等号的左边还是右边,
如果是等号左边就是setter方法, 在等号右边是getter方法


3. 点语法陷阱 :
在set方法使用self.
- (void)setAge:(int)newAge {
    self.age = newAge;
}

4、点语法注意
点语法的本质是方法的调用,而不是访问成员变量,当使用点语法时,编译器会自动展开成相应的方法。

切记点语法的本质是转换成相应的set和get方法,如果没有set和get方法,则不能使用点语 法。


/*--------------------------下午:----------------------------*/

四.@property关键字和@synthesize关键字:

(一),@property用法:
    1,@property是编译器的指令;
    2,@property的语法:
        @property int age;
        (这句话的意思,就是帮我们生成age 的get和set方法的声明)(xcode4.4以前)
        -(void)setAge:(int)age;
        -(int)age;

    3,@property只能写在@interface @end中。


    4,xcode4.4以后property做了增强 不但帮助我们自动生成get/set方法的声明还帮助我们自动生成get/set方法的实现 。


    5,告诉编译器,要生成的get/set方法声明的成员变量类型是int 。


    6,如果没有手动声明成员变量,perperty会在.m文件中自动帮我们生成一个开头的成员变量



(二),@synthesize用法:
    1. @synthesize age;
        1),生成一个age的实例变量;
        2),生成实例变量的get和set方法的实现

    2. @synthesize 给指定的实例变量赋值。
        @synthesize age = _age;

注意;
    如果是@synthesize的话, 变量名要先在.h文件中声明。
    @property,@synthesize这两个可以配合使用,用于简化set和get方法的定义和实现。


(三),xcode4.4之后
@property的增强用法:
    @property int age;这句话干了三件事:

    1,在.h文件中生成age的get和set方法的声明;
        @interface Person : NSObject
            -(void)setAge:(int)age;
            -(int)age;
        @end

    2,在.m文件中生成_age的私有实例变量;(前提是,没有在.h文件中手动声明_age变量)
        @implementation Person{
            int _age;//不能被子类继承
        }

        @end

    3,在.m文件中生成age的get和set方法的实现;
        @implementation Person{
            int _age;
        }
        -(void)setAge:(int)age{
            _age = age;
        }
        -(int)age{
            return _age;
        }
        @end


(四),在增强@property下,重写setter和getter方法:

    在使用@property情况下,重写setter, getter方法时,
    只能重写setter, 或者getter方法中的一个
    如果重写两个会报错.


五.动态类型
1. 动态类型:
    程序在运行的时候才能确定的类型;
        比如:1),多态;Animal *ani = [Dog new];
                   [ani run];
            2),id类型;

    静态类型:就是程序在编译时就能确定的类型;

2. id类型:
        称为万能指针,可以指向任何继承自NSObject的对象.
        id类型是属于动态类型,是在运行时检查类型;

注意:
    id只能指向对象类型,不能指向非对象类型;


3,NSObject和id的区别:(面试题)
    (1),NSObject和id都可以指向任何对象。
        NSObject *obj = [Animal new];
        id obj1 = [Animal new];

    (2),NSObject对象会进行编译时检查,需要强制类型转换;
        [(Animal*)obj run]; //动物再跑

    (3,)id类型不需要强制转换,可以直接使用。编译器看到id以后,认为是动态类型,不在检查类型。
        [obj1 run];


4,instancetype和id的异同:(面试题)
    相同点: 都可以作为方法的返回类型
    不同点:
        1),instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;
        2),instancetype只能作为返回值,不能像id那样作为参数,

第六天


一. 动态类型检测
/**********************对象和类之间的判断***********************/
1、isKindOfClass:Class
判断实例对象是否是这个类或者这个类的子类的实
例。

2、isMemberOfClass:Class
判断对象是否是这个类的实例。


/**********************类和类之间的判断*******************/
3、+(BOOL) isSubclassOfClass:classObj
判断类是否是指定类的子类。
格式: [类A isSubclassOfClass:类B];
判断类A是否是类B的子类;  是 YES   不是 NO



/**********************对象和方法之间的判断*******************/
4、- (BOOL)respondsToSelector:(SEL)aSelector;   用的比较多;
判断对象是否可以调用这个方法;

5、+ (BOOL)instancesRespondToSelector:(SEL)aSelector;
判断类是否有这个方法。此方法是类方法, 不能用在类的对象

/**********************方法的执行*******************/
6,响应方法
-(id) performSelector:selector(应用selector指定的方法) NSObject的方法
// 一个参数
-(id) performSelector:selector withObject:object(应用selector指定的方法,传递参数 object)
// 二个参数
-(id) performSelector:selector withObject:object1 withObject:object2(应用selector指 定的方法,传递参数object1和object2)






3. 自定义构造方法的使用注意
(1). 自己做自己的事情
(2). 父类的方法交给父类的方法来处理,子类的方法处理子类自己独有的属性


4. 使用场景
如果对象被创建的时候, 需要对里面某些属性进行初始化(设置), 这个时候就可以使用构造方法


5,instancetype和id的作为返回值的区别;
instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;



4 个回复

倒序浏览
想发一个 全部的,可是最大字节 10000 有限制,╮(╯▽╰)╭  下次把
回复 使用道具 举报
赞一个
回复 使用道具 举报
好的,我们等着呢
回复 使用道具 举报
天鹰的空 发表于 2015-8-28 23:37
想发一个 全部的,可是最大字节 10000 有限制,╮(╯▽╰)╭  下次把

嗯,确实是有字数限制的,我有时候就是分两次发的,命名为上下两部分
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马