Objective-C第四章多态

你好!我是小柒,今天我们学习一下多态。

多态

 

本节内容

1、多态

2、复合

 

一、多态

 例如:有一个人使用,黑白打印机,彩色打印机。

由于需求不同:

彩色打印机打印的效果是彩色的。

黑白打印机打印的效果是黑白的。

分析:

首先我由于黑白打印机,彩色打印机都是打印机,我们是不是可以定义一个打印机类,让黑白打印机,彩色打印机都继承与打印机类,这样就可以把黑白打印机,彩色打印机的都有的属性和方法给打印机,可以减轻代码量。

 继承版代码:

 //  Printer.h打印机类

#import <Foundation/Foundation.h>

 @interface Printer : NSObject

//共同点打印

-(void)print;

@end

 

//  Printer.m打印机类

#import "Printer.h"

@implementation Printer

-(void)print

{

    NSLog(@"打印");

}

@end

 

 

//Colorprinter.h彩色打印机

#import "Printer.h"

@interface Colorprinter : Printer

@end

 

//  Colorprinter.m

#import "Colorprinter.h"

@implementation Colorprinter

//重写父类方法

-(void)print

{

    NSLog(@"彩色打印机,打印彩色效果");

}

@end

 

//  Blackprinter.h黑白打印机

#import "Printer.h"

@interface Blackprinter : Printer

 

@end

 

//  Blackprinter.m

#import "Blackprinter.h"

 

@implementation Blackprinter

//重写父类方法

-(void)print

{

    NSLog(@"黑白打印机,打印黑白效果");

}

@end

 

//  Person.h人类

#import <Foundation/Foundation.h>

//导入头文件

#import "Blackprinter.h"

#import "Colorprinter.h"

@interface Person : NSObject

//人使用黑白打印机

-(void)blackPrinter:(Blackprinter *)black;

//人使用彩色打印机

-(void)colorPrinter:(Colorprinter *)color;

@end

 

//  Person.m人类

#import "Person.h"

 

@implementation Person

 

-(void)blackPrinter:(Blackprinter *)black

{

//    调用黑白打印机方法

    [black print];

    NSLog(@"使用黑白打印机");

}

 

-(void)colorPrinter:(Colorprinter *)color

{

//    调用彩色打印机方法

    [color print];

    NSLog(@"使用彩色打印机");

}

@end

 

//  main.m调用

#import <Foundation/Foundation.h>

//导入头文件

#import "Person.h"

#import "Colorprinter.h"

#import "Blackprinter.h"

int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Person *person = [[Person alloc] init];

        Colorprinter *colorPrinter = [[Colorprinter alloc] init];

        Blackprinter *blackPrinter = [[Blackprinter alloc] init];

//        人使用黑白打印机

        [person blackPrinter:blackPrinter];

//        人使用彩色打印机

        [person colorPrinter:colorPrinter];

    }

    return 0;

}

 

打印效果:

 2015-12-30 19:08:44.960 Task[4873:186510] 黑白打印机,打印黑白效果

2015-12-30 19:08:44.961 Task[4873:186510] 使用黑白打印机

2015-12-30 19:08:44.961 Task[4873:186510] 彩色打印机,打印彩色效果

2015-12-30 19:08:44.961 Task[4873:186510] 使用彩色打印机

 

 

但是现在需求变了,我要在增加一个3D打印机。

我们怎么写:

1、可以用上一个代码的方式来书写,我们说假如做一个app,版本得升级更新吧!不能总是1.0版本吧!但是为了尽量出现避免一些问题,所以说原来的代码能不改就不改。

2、用多态来写,不需要改动。

小柒什么多态啊?

答:多态是指同一种类型,具有多种表现形态。

小柒什么情况下可以用多态啊?

1、必须存在继承关系

2、子类重写父类的方法

3、父类声明的变量指向子类对象

 

多态版代码:

 

//  Printer.h打印机类

#import <Foundation/Foundation.h>

 @interface Printer : NSObject

//共同点打印

-(void)print;

@end

 

//  Printer.m打印机类

#import "Printer.h"

@implementation Printer

-(void)print

{

    NSLog(@"打印");

}

@end

 

 

//Colorprinter.h彩色打印机

#import "Printer.h"

@interface Colorprinter : Printer

@end

 

//  Colorprinter.m

#import "Colorprinter.h"

@implementation Colorprinter

//重写父类方法

-(void)print

{

    NSLog(@"彩色打印机,打印彩色效果");

}

@end

 

//  Blackprinter.h黑白打印机

#import "Printer.h"

@interface Blackprinter : Printer

 

@end

 

//  Blackprinter.m

#import "Blackprinter.h"

 

@implementation Blackprinter

//重写父类方法

-(void)print

{

    NSLog(@"黑白打印机,打印黑白效果");

}

@end

 

//  Models.h3D打印机

#import "Printer.h"

 @interface Models : Printer

 

@end

 

//  Models.m

#import "Models.h"

 @implementation Models

-(void)print

{

    NSLog(@"3D打印机打印能立体效果");

}

@end

 

//  Person.h人类

#import <Foundation/Foundation.h>

//彩色打印机

#import "Colorprinter.h"

//黑白打印机

#import "Blackprinter.h"

//3D打印机

#import "Models.h"

@interface Person : NSObject

//多态方法

//-(返回类型)方法名:(类型)参数名;

-(void)doPrinter:(Printer *)printer;

@end

 

//  Person.m

#import "Person.h"

 @implementation Person

//多态方法

//-(返回类型)方法名:(类型)参数名;

-(void)doPrinter:(Printer *)printer

{

//    调用打印机方法

//  [参数名 方法名];

//  print打印机类的方法

    [printer print];

 

}

@end

 

//  main.m

#import <Foundation/Foundation.h>

#import "Person.h"

#import "Printer.h"

int main(int argc, const char * argv[]) {

    @autoreleasepool {

//        创建人对象

        Person *person = [[Person alloc] init];

//        彩色打印机

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

//        父类 *对象名 = [[子类名 alloc] init];

        Printer *colorPR = [[Colorprinter alloc] init];

//        黑白打印机

        Printer *blackPR = [[Blackprinter alloc] init];

        Printer *modelsPR = [[Models alloc] init];

 //  只要创建继承于打印机类的打印机对象,都可以使用这个方法

//      [person doPrinter:(Printer *)]

//        人使用彩色打印机

        [person doPrinter:colorPR];

//        人使用黑白打印机

        [person doPrinter:blackPR];

//        人使用3D打印机

        [person doPrinter:modelsPR];

          }

    return 0;

}

 

打印结果:

2015-12-30 20:17:39.634 Task2[5583:214553] 彩色打印机打印彩色效果

2015-12-30 20:17:39.635 Task2[5583:214553] 黑白打印机能打印黑白效果

2015-12-30 20:17:39.635 Task2[5583:214553] 3D打印机打印能立体效果

 

复合

小柒什么是复合?

答:多个组件组合在一起,形成一个整体,然后使用整体进行工作,这种组合称为复合。

严格讲,只有对象间的组合才能叫做复合,像int、float等基本数据类型被认为是对象的一部分

 

#import

 从开始学习OC,我们就对#import有过接触,他的作用时导入文件,今天我们就来系统的认识一下#import。

1、#import的作用:导入文件,相当于将文件的内容进行拷贝。

在工程里创建两个类:Student类,Teacher类

 

Student.h

#import <Foundation/Foundation.h>

//#import导入文件,相当于将Teacher.h里的内容拷贝到Student.h文件中,这样可以得到Teacher.h文件的所有信息。

#import "Teacher.h"

@interface Student : NSObject

{

//    创建myTeacher对象

    Teacher *myTeacher;

}

@end

 

小柒还记得#include吗?

在OC第一天的课程中对#include和#import进行了讲解

#include不能重复导入文件,#import可以重复导入文件,不会报错。

2、使用#import时需要注意一个问题,避免循环引言。

如例:

 

Student.h

 #import <Foundation/Foundation.h>

//#import导入文件,相当于将Teacher.h里的内容拷贝到Student.h文件中,这样可以得到Teacher.h文件的所有信息。

#import "Teacher.h"

 @interface Student : NSObject

{

//    创建myTeacher对象

//    未知的类型名称“老师”报错信息

    Teacher *myTeacher;

}

@end

 

Teacher.h

#import <Foundation/Foundation.h>

//在Teacher导入Student.h

#import "Student.h"

@interface Teacher : NSObject

{

//    会报错

//    未知的类型名称“学生”报错信息

    Student *student;

}

@end

3、小柒如何解决这个问题呢?

大神们早就给咱们准备好了方案

用@class Student;来操作

 

Student.h

#import <Foundation/Foundation.h>

//#import导入文件,相当于将Teacher.h里的内容拷贝到Student.h文件中,这样可以得到Teacher.h文件的所有信息。

#import "Teacher.h"

@interface Student : NSObject

{

    Teacher *myTeacher;

}

@end

 

Teacher.h

#import <Foundation/Foundation.h>

//在Teacher导入Student.h

@class Student;

@interface Teacher : NSObject

{

    Student *student;

}

@end

不会报错

小柒什么是@class?

答:@class是告诉编译器,某个字段知识作为类名使用,不知道类接口里的信息。

今天的课程就结束,小柒感谢你们的陪伴,多敲代码,记得预习Foundation框架的字符串与可变字符串。

 

posted on 2015-12-30 14:06  xxQMYxx  阅读(211)  评论(0)    收藏  举报

导航