學(xué)過面向?qū)ο笳Z(yǔ)言的小伙伴都知道,面向?qū)ο蟮恼Z(yǔ)言(Java,C#,OC)都有三大特性:封裝、繼承、多態(tài)。
所謂封裝,在OC中就是把變量和方法封裝到一個(gè)類中;繼承就是如果一個(gè)子類繼承一個(gè)父類,那么子類就可以直接用父類的變量和方法,大大減少了代碼的書寫量并且提高了代碼的可維護(hù)性(只要在父類中修改其中的變量和方法,子類繼承過來(lái)的變量和方法也會(huì)隨著改變,必須要一一修改);多態(tài),從字面上理解就是多種形態(tài),但僅僅知道這么多,怎么好意思說自己是學(xué)過面向?qū)ο蟮哪兀?/p>
下面本人就板門弄斧的談?wù)勛约簩?duì)多態(tài)的理解:
首先從多態(tài)的定義來(lái)說:
- 用一個(gè)父類的指針指向子類的對(duì)象,在函數(shù)(方法)調(diào)用的時(shí)候可以調(diào)用到正確版本的函數(shù)(方法)。
使用多態(tài)的條件:
1.子類必須重寫父類的方法
2.父類指針指向子類對(duì)象
多態(tài)的應(yīng)用場(chǎng)景:
- 用一個(gè)父類的指針指向子類的對(duì)象
****主函數(shù)****
#import <Foundation/Foundation.h>
//導(dǎo)入頭文件
#import "Osier.h"
#import "PineTree.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//父類的指針指向子類的對(duì)象
Tree *t1 = [[Osier alloc] init];
[t1 grow];
Tree *t2 = [[PineTree alloc] init];
[t2 grow];
}
return 0;
}
輸出結(jié)果為:
柳樹在春天發(fā)芽
松樹四季常青
****父類(Tree)的文件****
//.h聲明文件
#import <Foundation/Foundation.h>
@interface Tree : NSObject
@property NSString *name;
@property int age;
-(void)grow;
@end
//.m實(shí)現(xiàn)文件
#import "Tree.h"
@implementation Tree
-(void)grow
{
NSLog(@"樹木生長(zhǎng)");
}
@end
****子類(Osier)文件****
//.h聲明文件
#import "Tree.h"
//柳樹繼承樹這個(gè)類
@interface Osier : Tree
//重寫父類grow方法
-(void)grow;
@end
//.m實(shí)現(xiàn)文件
#import "Osier.h"
@implementation Osier
-(void)grow
{
NSLog(@"柳樹在春天發(fā)芽");
}
@end
****子類(PineTree)文件****
//.h聲明文件
#import "Tree.h"
//松樹繼承樹類
@interface PineTree : Tree
//重寫父類的grow方法
-(void)grow;
@end
//.m實(shí)現(xiàn)文件
#import "PineTree.h"
@implementation PineTree
-(void)grow
{
NSLog(@"松樹四季常青");
}
@end
-
用一個(gè)父類的指針當(dāng)函數(shù)參數(shù),用這個(gè)指針可以接受任何它的子類對(duì)象包括它自己。
****其他文件不變,只在主函數(shù)中改變,代碼如下****
//其他文件不變,只在主函數(shù)中改變
#import <Foundation/Foundation.h>
#import "Osier.h"
#import "PineTree.h"
//定義一個(gè)函數(shù),用父類指針作形參
void grow(Tree *t)
{
[t grow];
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
Tree *t0 = [[Tree alloc] init];
grow(t0);
Tree *t1 = [[Osier alloc] init];
grow(t1);
Tree *t2 = [[PineTree alloc] init];
grow(t2);
}
return 0;
}
//輸出結(jié)果為:
樹木生長(zhǎng)
柳樹在春天發(fā)芽
松樹四季常青
- 在復(fù)合類中,盡量引用高層次的類(父類)的指針當(dāng)作復(fù)合類的成員變量,這樣就可以通過它(父類的指針)創(chuàng)建出它所對(duì)應(yīng)的任何子類對(duì)象包括它自己。
****定義一個(gè)復(fù)合類Person****
//定義一個(gè)復(fù)合類Person
#import <Foundation/Foundation.h>
//前向?qū)?@class Tree;
@class Osier;
@class PineTree;
//定義一個(gè)萬(wàn)能的Person類
@interface Person : NSObject
@property(nonatomic, retain) NSString *name;
@property(nonatomic, assign) int age;
@property(nonatomic, retain) Tree *tree;
-(instancetype)initWithName:(NSString *)name andAge:(int)age;
@end
//Person .m實(shí)現(xiàn)文件
#import "Person.h"
#import "Tree.h"
#import "Osier.h"
#import "PineTree.h"
@implementation Person
-(instancetype)initWithName:(NSString *)name andAge:(int)age
{
if(self = [super init])
{
_name = name;
_age = age;
_tree = [[PineTree alloc] init];
}
return self;
}
-(NSString *)description
{
return [NSString stringWithFormat:@"name = %@, age = %i", _name, _age];
}
@end
**** 主函數(shù)****
#import <Foundation/Foundation.h>
#import "Osier.h"
#import "PineTree.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [[Person alloc]initWithName:@"小明" andAge:15];
NSLog(@"%@", p);
[p.tree grow];
}
return 0;
}
//輸出結(jié)果:
name = 小明, age = 15
松樹四季常青
總結(jié):
多態(tài)的優(yōu)點(diǎn)是提高程序的可擴(kuò)展性
最后,如果有錯(cuò)誤,請(qǐng)大牛們指點(diǎn)!本文僅供參考。