OC语法之多态
来源:互联网 发布:淘宝店铺买卖 安全吗 编辑:程序博客网 时间:2024/05/16 00:31
OC指针类型的变量有两个:一个是编译时类型,一个是运行时类型,编译时的类型由声明该变量时使用的类型决定,运行时的类型有实际赋给该变量的对象决定.如果编译类型和运行类型不一致,就可能出现多态.
下面直接上代码:
一:多态性
#import <Foundation/Foundation.h>//定义一个基本类型@interface SHBase : NSObject-(void)base;-(void)test;@end#import "SHBase.h"@implementation SHBase- (void) base{ NSLog(@"父类的普通base方法");}- (void) test{ NSLog(@"父类的将被覆盖的test方法");}@end#import "SHBase.h"//定义一个子类@interface SHSubclass : SHBase-(void)sub;@end#import "SHSubclass.h"@implementation SHSubclass//重写父类的test方法- (void) test{ NSLog(@"子类的覆盖父类的test方法");}- (void) sub{ NSLog(@"子类的sub方法");}@end/** * 多态性 */-(void)testOne{ // 下面编译时类型和运行时类型完全一样,因此不存在多态 SHBase *base = [[SHBase alloc] init]; // 下面两次调用将执行BaseClass的方法 [base base]; [base test]; // 下面编译时类型和运行时类型完全一样,因此不存在多态 SHSubclass* subclass = [[SHSubclass alloc] init]; // 下面调用将执行从父类继承到的base方法 [subclass base]; // 下面调用将执行子类重写的test方法 [subclass test]; // 下面调用将执行子类定义的sub方法 [subclass sub]; // 下面编译时类型和运行时类型不一样,多态发生,编译的时候是SHBase类型,运行时是SHSubclass类型. // 因为子类其实是一种特殊的父类,因此 OC 允许把一个子类对象直接赋值给一个父类指针变量,无需任何类型装换. // 注意了:调用的时候方法行为总是表现子类方法的行为特征,而不是父类的方法.这里就是:相同类型的变量调用同一个方法 // 时呈现多种不同的行为特征,那就是多态. SHBase* ploymophicBc = [[SHSubclass alloc] init]; // 下面调用将执行从父类继承到的base方法 [ploymophicBc base]; // 下面调用将执行子类重写的test方法 [ploymophicBc test]; // 因为ploymophicBc的编译类型是FKBase // FKBase类没有提供sub方法,所以下面代码编译时会出现错误。 // [ploymophicBc sub]; // 可将任何类型的指针变量赋值给id类型的变量,为了解决编译类型的检査问题,可以使用 id类型, // 程序可以对任何对象或者任何类型的指针变量赋值为 id 类型的变量,而且使用 id 类型可以调用 // 该变量实际所指对象的方法. id dyna = ploymophicBc; [dyna sub];// 2016-01-08 18:50:13.091 OC 多态[4748:2315316] 父类的普通base方法// 2016-01-08 18:50:13.092 OC 多态[4748:2315316] 父类的将被覆盖的test方法// 2016-01-08 18:50:13.092 OC 多态[4748:2315316] 父类的普通base方法// 2016-01-08 18:50:13.092 OC 多态[4748:2315316] 子类的覆盖父类的test方法// 2016-01-08 18:50:13.092 OC 多态[4748:2315316] 子类的sub方法// 2016-01-08 18:50:13.092 OC 多态[4748:2315316] 父类的普通base方法// 2016-01-08 18:50:13.092 OC 多态[4748:2315316] 子类的覆盖父类的test方法// 2016-01-08 18:50:13.092 OC 多态[4748:2315316] 子类的sub方法}
二:指针变量的强制类型转换
/** * 指针变量的强制类型转换 */-(void)testTwo{ /* 注意:强制类型转换只是改变了该指针变量的编译类型,但是该变量所指向对象的实际 类型并不会发生改变,如果程序不断进行转换,转换出来的变量在调用方法时就会引发错误. */ // 声明hello时使用NSObject类,则hello的编译时类型是NSObject, // NSObject是所有类的父类 , 但hello变量的实际类型是NSString NSObject *obj = @"Hello"; // 由于obj变量所指向的对象是NSString对象,所以运行时也可通过 NSString* objStr = (NSString*)obj; NSLog(@"%@" , objStr); // 定义一个obj2变量,编译类型为NSObject,实际类型为NSString NSObject* obj2 = @"iOS"; // 尝试将obj2强转为NSDate,这行代码没有任何问题 // 但程序只是定义一个NSDate类型的指针,该指针与obj2指向同一个对象 NSDate* date = (NSDate*)obj2; // 程序调用date的isEqualToDate:方法。 // 由于date的编译时类型是NSDate,因此编译时没有任何问题 // 由于date实际指向的对象是NSString,因此程序执行时就会引发错误, NSLog(@"%d" , [date isEqualToDate:[NSDate date]]); /* 程序奔溃: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString isEqualToDate:]: unrecognized selector sent to instance 0x5054 字符串并没有isEqualToDate方法. */}
三:判断指针变量的实际类型
/** * 判断指针变量的实际类型 */-(void)testThree{ /* 注意:为了保证程序能够正常运行,一般建议在执行强转之前先判断该对象是否为该类,或者其子类.判断指针变量实际指向的对象是否为某个类,某个子类,可以使用如下方法: - (BOOL)isKindOfClass:(Class)aClass; 判断对象是否为aClass类 - (BOOL)isMemberOfClass:(Class)aClass; 判断对象是否为aClass类的实例. */ NSObject* hello = @"Hello"; // 使用isKindOfClass判断该变量所指的对象是否为指定类、及其子类的实例 NSLog(@"字符串是否是NSObject类的实例:%d" , ([hello isKindOfClass:[NSObject class]])); // 返回true。 NSLog(@"字符串是否是NSString类的实例:%d" , ([hello isKindOfClass:[NSString class]])); // 返回false。 NSLog(@"字符串是否是NSDate类的实例:%d" , ([hello isKindOfClass:[NSDate class]])); NSString* a = @"Hello"; // 返回false NSLog(@"a是否是NSDate类的实例:%d" , ([a isKindOfClass:[NSDate class]]));}
0 0
- OC语法之多态
- OC之多态
- OC之多态
- oc学习之多态
- C++语法之多态
- OC面向对象之多态
- 面向对象OC之多态
- OC学习笔记之多态
- OC学习笔记之多态
- Java基础语法之多态
- 黑马程序员-OC语言之多态
- 黑马程序员——oc之多态
- OC的三大特性之多态
- OC学习之多态初解
- OC之多线程
- OC基础—三大特性之多态
- 黑马程序员-OC学习日记五之多态
- OC-语法
- UITableView、 UITableViewCell
- UIViewController中各方法调用顺序及功能详解
- 【BZOJ 1503】 郁闷的出纳员
- Android中的windowSoftInputMode属性详解
- 线上性能问题初步排查方法
- OC语法之多态
- 寻找最大数 OJ 448
- CollectionView和layout的使用,瀑布流
- mipmap和drawable一个使用的区别
- Objective-C单例模式的正确写法
- Script入门篇
- 大蒟蒻的1557
- 最少步数 OJ 58
- ibatis xml特别的用法