Objective-C第三章封装和继承

你好!我是小柒,今天我们来学习一下面向对象三大特性的封装和继承。

封装

本节内容:

1、封装

2、继承

3、再谈self和super

4、方法重写

一、封装

小柒什么是面向对象的三大特性?

答:封装,继承,多态。

小柒什么是封装?

答:隐藏属性、方法或实现细节的过程称为封装。对象同时具有属性和方法两项特性,对象的属性和方法通常被封装在一起,共同体现事物的特性,二者相辅相承,不能分割。

例如:汽车的零件、发动机、地盘等都封装在汽车内部。

例如:两种或多种化学药品组成一个胶囊。信息隐藏,隐藏对象的实现细节,不让用户看到,将东西包装在一起,然后以新的完整形式呈现出来。

第一种:

//  Student.h声明文件

#import <Foundation/Foundation.h>

 @interface Student : NSObject

//1、当属性名和成员变量名一样时,如果我们对成员变量的值不强求,但我们又想打印赋上的值,这时在.m里可以使用_属性名 或者 self.属性名

{

//    成员变量

    NSString *name;

}

@property NSString *name;

-(void)sayHi;

 

@end

 

//Student.m实现文件

#import "Student.h"

@implementation Student

-(void)sayHi

{

    NSLog(@"name = %@ ",_name);

    NSLog(@"name1 = %@",self.name);

}

@end

//  main.m调用

#import <Foundation/Foundation.h>

#import "Student.h"

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

    @autoreleasepool {

        Student *stu = [[Student allocinit];

        stu.name = @"老王";

        [stu sayHi];

    }

    return 0;

}

打印结果:

2015-12-29 20:20:13.899 OC3.13[3390:78731] name = 老王 

2015-12-29 20:20:13.900 OC3.13[3390:78731] name1 = 老王

 

第二种:

//  Student.h

#import <Foundation/Foundation.h>

 @interface Student : NSObject

//2、当定义一个属性时,会首先查找是否有以_属性名命名的成员变量,如果有,则默认对其进行setget,如果没有,则隐式生成以_属性名命名的变量

{

    NSString *_name;

}

@property NSString *name;

 

-(void)sayHi;

 

@end

 

//  Student.m

 

#import "Student.h"

 @implementation Student

-(void)sayHi

{

    NSLog(@"name = %@",_name);

    NSLog(@"name11 = %@",self.name);

}

@end

 

//  main.m

#import <Foundation/Foundation.h>

#import "Student.h"

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

    @autoreleasepool {

        Student *stu = [[Student alloc] init];

        stu.name = @"老王";

        [stu sayHi];

    }

    return 0;

}

打印结果:

2015-12-29 20:26:56.441 OC3.14[3554:82571] name = 老王

2015-12-29 20:26:56.442 OC3.14[3554:82571] name11 = 老王

 

第三种:

//  Student.h

#import <Foundation/Foundation.h>

 @interface Student : NSObject

//属性定义

@property NSString *name;

@property int age;

-(void)sayHi;

@end

 

//  Student.m

#import "Student.h"

 @implementation Student

@synthesize name,age;

//3、当属性名和成员变量名一样时,如果我们想保证成员变量有值,那么就需要在.m中加入@synthesize 变量名@synthesize name,age;

-(void)sayHi

{

    NSLog(@"我是%@%d",name,age );

}

@end

 

//  main.m

#import <Foundation/Foundation.h>

#import "Student.h"

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

    @autoreleasepool {

        Student *stu = [[Student alloc] init];

//        点语法

        stu.name = @"老王";

        stu.age = 12;

        [stu sayHi];

    }

    return 0;

}

打印结果:

2015-12-29 20:30:05.913 OC3.12[3668:84857] 我是老王12

 

第四种:

//  Student.h

#import <Foundation/Foundation.h>

 @interface Student : NSObject

//4、当我们使用属性时,成员变量可以省略

@property NSString *name;

-(void)sayHi;

@end

 

//  Student.m

#import "Student.h"

 @implementation Student

-(void)sayHi

{

    NSLog(@"name = %@",_name);

    NSLog(@"name11 = %@",self.name);

}

@end

 

//  main.m

#import <Foundation/Foundation.h>

#import "Student.h"

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

    @autoreleasepool {

        Student *stu = [[Student alloc] init];

        stu.name = @"老王";

        [stu sayHi];

    }

    return 0;

}

打印结果:

2015-12-29 20:31:49.480 OC3.15[3807:86304] name = 老王

2015-12-29 20:31:49.482 OC3.15[3807:86304] name11 = 老王

 

继承

二、继承

先看几个小例子:

 食肉动物,食草动物,杂食动物;

出租车,大货车,大巴车;

苹果电脑,三星电脑,戴尔电脑;

小学生,中学生,打学生;

猜猜谁是父类

动物,汽车,电脑,学生

猜猜谁是子类

食肉动物、食草动物、杂食动物,苹果电脑、三星电脑、戴尔电脑,小学生、中学生、打学生。

以出租车,大卡车,大巴车为例:

车类:属性有品牌、颜色,方法有启动,刹车,加速减速。

出租车特性——打票,所属公司

大卡车特性——最大载重 ,卸货

大巴车特性——载客量大,报站

小柒什么是继承?

答:子类具有父类的一般特性(包括属性和行为),以及自身独特的特性,子类自动继承父类的属性和方法,被继承的类叫超类或父类,继承超类的类叫子类或派生类,且OC语言的类都是单继承,所有类最后的父类都是继承于NSObject。

小柒为什么需要继承?

答:编程时减轻代码量

假如说,有两个类,他们有如下属性和方法

定义大卡车类:属性品牌,颜色,最大载重 方法:刹车,加速,卸货

定义出租车类:属性品牌,颜色,所属公司    方法:刹车,加速,打票

其实,这两个类的定义有什么问题?

答:代码存在重复

小柒有没有可能建立继承关系,让子类自动继承父类的属性和方法?

答:有继承关系,都是车,创建一个父类,就叫车类。

具体思路————

首先,我们可以创建3个类,一、创建父类,车类把共有属性和共有方法写在一起,二、创建两个子类,这样就能继承父类的属性和方法,大卡车类,出租车类,将特有的属性和特有大方法

写在大卡车类和出租车类里。

具体分类————

父类车类:共有的属性品牌、颜色,共有的方法刹车,加速

子类大卡车类:特有属性:最大载重 特有方法:卸货

子类出租车类:特有属性:所属公司 特有方法:打票

思路有了,我们回到Xcode,创建好一个工程,再创建一个父类,再创建子类。

操作步骤:

1、先创建好一个工程(Objective-C第一章类和对象中图1—4)

2、创建父类command+n创建父个类,第一项Class:父类名,注意第二项Subclass of:NSObject第三项Also不勾选,第四项Language:Objective-C/@interface car : NSObject

(Objective-C第一章类和对象中图9)

3、创建子类command+n创建一个子类,第一项Class:子类名,

注意:Subclass of:父类名,第三项Also不勾选,第四项Language:Objective-C/@interface Taxi : car

(如图1.1)

图1.1

 

具体代码————

//  car.h

#import <Foundation/Foundation.h>

//父类

@interface car : NSObject

//品牌

@property NSString *Brand;

//颜色

@property NSString *Color;

//加速

-(void)speed;

//刹车

-(void)Brake;

//

-(void)fly;

@end

 

 

//  car.m

#import "car.h"

 @implementation car

-(void)speed

{

    NSLog(@"我叫%@,颜色是:%@,我在加速",_Brand,_Color);

}

-(void)Brake

{

    NSLog(@"我叫%@,颜色是:%@,我在减速",_Brand,_Color);

}

-(void)fly

{

    NSLog(@"%@有抱负,天高任车飞",_Brand);

}

@end

 

//  Taxi.h

//头文件不一样了

#import "car.h"

//子类出租车

@interface Taxi : car

//所属公司

@property NSString *company;

//打票

-(void)buy;

@end

 

//  Taxi.m

#import "Taxi.h"

 @implementation Taxi

//打票

-(void)buy

{

//self子类里面调用当前类方法,如果当前类没有,则调用父类方法。

//fly父类里面的方法

    [self fly];

    NSLog(@"%@是出租车,我能打票",self.Brand);

    }

@end

 

//  Truck.h

#import "car.h"

//子类货车

@interface Truck : car

//重量

@property int heft;

//卸货

-(void)unload;

@end

 

//  Truck.m

#import "Truck.h"

 @implementation Truck

-(void)unload

{

//  super直接调用父类方法

//fly父类里面的方法

    [super fly];

    NSLog(@"%@是货车,到站了卸货吧",self.Brand);

}

 

//方法重写

//通过方法重写,子类可以改变从父类继承的行为。

//要求:被重写的方法定义必须与父类中的方法完全一样。

 

 

//父类方法

 

//加速

 

-(void)speed

 

{

 

    NSLog(@"汽车没油了加毛线速啊");

 

}

 

@end

 

//  main.m

#import <Foundation/Foundation.h>

#import "car.h"

#import "Taxi.h"

#import "Truck.h"

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

    @autoreleasepool {

//        父类

        car *ar = [[car alloc] init];

        ar.Brand = @"大黄";

        ar.Color = @"白色";

        [ar speed];

        [ar Brake];

        NSLog(@"__________________________");

//        子类

        Taxi *taxi = [[Taxi alloc] init];

//        子类继承父类的品牌

        taxi.Brand = @"老黑";

//        子类继承父类的颜色

        taxi.Color = @"黑色";

//        子类继承父类的加速方法

        [taxi speed];

//        子类继承父类的减速方法

        [taxi Brake];

//        子类自己特有的方法打票

        [taxi buy];

        NSLog(@"__________________________");

 

       Truck *truck = [[Truck alloc] init];

        truck.Brand = @"汗血老马";

        truck.Color = @"红色";

        [truck speed];

        [truck Brake];

        [truck unload];

        NSLog(@"__________________________");

    }

    return 0;

}

 

打印结果:

2015-12-30 14:33:53.848 Task[2856:113463] 我叫大黄,颜色是:白色,我在加速

2015-12-30 14:33:53.849 Task[2856:113463] 我叫大黄,颜色是:白色,我在减速

2015-12-30 14:33:53.849 Task[2856:113463] __________________________

2015-12-30 14:33:53.850 Task[2856:113463] 我叫老黑,颜色是:黑色,我在加速

2015-12-30 14:33:53.850 Task[2856:113463] 我叫老黑,颜色是:黑色,我在减速

2015-12-30 14:33:53.850 Task[2856:113463] 老黑有抱负,天高任车飞

2015-12-30 14:33:53.850 Task[2856:113463] 老黑是出租车,我能打票

2015-12-30 14:33:53.850 Task[2856:113463] __________________________

2015-12-30 14:33:53.850 Task[2856:113463] 汽车没油了加毛线速啊

2015-12-30 14:33:53.850 Task[2856:113463] 我叫汗血老马,颜色是:红色,我在减速

2015-12-30 14:33:53.850 Task[2856:113463] 汗血老马有抱负,天高任车飞

2015-12-30 14:33:53.850 Task[2856:113463] 汗血老马是货车,到站了卸货吧

2015-12-30 14:33:53.850 Task[2856:113463] __________________________

 

 

关键字self和super

三、再谈self和super

1、self子类里面调用当前类方法,如果当前类没有,则调用父类方法。 (代码在Taxi.m)

 

2、super直接调用父类方法。( 代码在Truck.m)

方法重写

 四、方法重写

小柒什么是方法重写?

通过方法重写,子类可以改变从父类继承的行为。

要求:被重写的方法定义必须与父类中的方法完全一样。

( 代码在Truck.m)

 

哎呀!今天的课程又讲完了,大家好好敲代码,记得预习多态,小柒也吃饭了,拜拜。加油哦!

 

 

posted on 2015-12-29 19:38  xxQMYxx  阅读(136)  评论(0编辑  收藏  举报

导航