首页 > 代码库 > 【OC学习-14】多态是什么?看父类方法在子类中复写产生的效果

【OC学习-14】多态是什么?看父类方法在子类中复写产生的效果

什么是多态?

官方说法:同一接口,不同实现方法。其实大白话就是(以父类和子类为例,实际上可以不限于这种关系):父类有一个方法(函数),派生出得很多子类也有这个方法(函数),但是每个方法(函数)里内容不同。当然方法相同是指这个方法的名字、返回值类型、参数个数类型都一样。


直接上例子:我们创建一个父类ASShape有个draw方法,派生出三个子类ASCircle,ASRectangle、ASTriangle各自也有一个draw,当然每个draw里内容不同,就是实现输出一个句子。

(1)先创建一个父类:

//ASShape.h文件
#import <Foundation/Foundation.h>
@interface ASShape : NSObject
-(void)draw;
@end

//ASShape.m文件
#import <Foundation/Foundation.h>
@interface ASShape : NSObject
-(void)draw;
@end
(2)再创建三个子类,draw方法相同,里面内容不同,以下只列出一个,另外的ASCircle类和ASRectangle类自己冥想去。
//ASTriangle.h文件,继承ASShape类
#import "ASShape.h"
@interface ASTriangle : ASShape
-(void)draw;
@end

//基本和父类ASShape的draw类似,只是内容输出不同
#import "ASTriangle.h"
@implementation ASTriangle
-(void)draw{
    NSLog(@"triangle:draw");
}
@end
(3)再创建一个ASPerson类,借助这个类的paint方法把上面的类当做参数,并调用它们各自的draw方法

//ASPerson.h,要使用ASShape类,因为下面会用它创建对象
#import <Foundation/Foundation.h>
@class ASShape;
@interface ASPerson : NSObject
-(void)paint:(ASShape *)aShape;
@end

//ASPerson.m,需要导入各个头文件,不然它们各自的draw函数根本不能会调出来
#import "ASPerson.h"
#import "ASShape.h"
#import "ASCircle.h"
#import "ASRectangle.h"
#import "ASTriangle.h"
@implementation ASPerson
-(void)paint:(ASShape *)aShape{
    [aShape draw];
}
@end
(4)最后在main.m里面创建对象,并用这个对象去调用paint方法,由于paint方法的参数是ASShape类的对象,本应该调用ASShape类对象自己的draw函数,但是因为我们把ASShape子类实例化的对象当做参数传递给了paint,所以它们调用的就是各个子类自己的draw函数。这应该就是因为draw是多态的,所以调用哪个取决于你传递的参数吧。

#import <Foundation/Foundation.h>
#import "ASPerson.h"
#import "ASShape.h"
#import "ASCircle.h"
#import "ASRectangle.h"
#import "ASTriangle.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {
        ASPerson * person=[[ASPerson alloc]init];
        ASCircle * circle=[[ASCircle alloc]init];
        ASRectangle * rec=[[ASRectangle alloc]init];
        ASTriangle * tri=[[ASTriangle alloc]init];
        [person paint:circle];
        [person paint:rec];
        [person paint:tri];
    }
    return 0;
}

(5)运行结果

circle:draw
rectangle:draw
triangle:draw


注意事项:

a:把父类指定换成id通用指针,运行结果一样OK。id通用指针可以指向任何对象,指向谁就调用谁的方法(函数)。

@implementation ASPerson
-(void)paint:(id)aShape{
    [aShape draw];
}
@end

b:我们创建一个不集成ASShape的类叫ASExp,也给它定义一个draw方法。和上面操作步骤一致,先实例化一个对象对来,然后如下,发现结果也能输出,也就是说,这个多态并非一定要是父类和子类之间。

ASExp * exp=[[ASExp alloc]init];
[person paint:exp];

如果没有这个父类和子类的限制,或许能更明白多态,多态其实就是一个方法(函数)在不同类中写了很多个,具体执行时候,传递的时哪个类对象,就调用那个类对象的方法(函数)。

【OC学习-14】多态是什么?看父类方法在子类中复写产生的效果