黑马程序员——ios知识整理——关于继承、实例变量作用域、私有方法

来源:互联网 发布:天刀捏脸数据女 高冷 编辑:程序博客网 时间:2024/05/22 22:57

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


(以下均为个人理解,手动输入,如有错误,请您留言更正,谢谢)

一、关于继承的相关知识

继承是一个类将一个类的方法及变量接收过来,可以直接调用,同时在此基础上拥有自己独立的属性及方法。

A继承自B,那么B叫做A的父类或基类,A叫做B的子类或派生类。

继承的代码实现:

以交通方式为例:运输方式类作为父类,飞机类作为派生类

1.首先建立运输方式类:

(详细注意事项在单行注释中表明)

.h声明文件
#import <Foundation/Foundation.h>@interface transport : NSObject //此处运输方式作为car,plane的父类继承自NSObject//作为父类必须拥有普遍性的属性及方法,方便子类继承而不出现逻辑上的错误。//交通方式共有的属性,速度、名称、启动、停止@property(nonatomic,assign)float speed;@property(nonatomic,strong)NSString * name;-(void)start;-(void)stop;@end
.m实现文件

#import "transport.h"@implementation transport-(void)start{        NSLog(@"启动");    }-(void)stop{        NSLog(@"停止");    }@end

2.建立Plane派生类

注:为体现继承transport类的属性及方法,此处暂时不写Plane的属性及方法

.h声明文件

#import "transport.h"@interface Plane : transport//此处『:transport』代表Plane继承自transport类,类似的有transport继承自NSObject@end
.m实现文件

#import "Plane.h"@implementation Plane@end

main函数中调用及实现:

#import <Foundation/Foundation.h>#import "Plane.h"int main(int argc, const char * argv[]) {    @autoreleasepool {                Plane *p = [Plane new];        p.name = @"c919";        [p start];            }    return 0;}


运行结果:启动


可以看到,在main函数中直接引用Plane.h头文件即可实现在transport中声明的start方法,同时给p.name赋值,然而在我们的Plane类中并没有对其进行声明。


Plane作为一个独立的类,可以拥有自己特有的属性,如航高、航速等,可以正常声明,此处不做赘述。但是其继承的『启动』及『停止』方法,显然某些情况下不适用,这里我们可以对其继承的方法进行改写,以适应其特殊需要而不需要再单独声明。方法及步骤:


在Plane的.m实现文件中直接改写相关方法:

代码如下:

#import "Plane.h"@implementation Plane-(void)start{        NSLog(@"飞机起飞");    }@end
对其继承的方法直接进行改写,不需要再声明

main.h文件不需要修改直接运行,结果为:飞机起飞
同理,其他继承的方法同样可以修改,包括NSObject的方法


二、实例变量的作用域

修饰实例变量的访问修饰符:@public、@protected、@private、@package

在这建立一个新的类Car,演示访问修饰符的作用:

#import <Foundation/Foundation.h>#import "Plane.h"@interface Car : NSObject{        NSString * _name;    float _speed;    int _num;    }-(void)setNum:(int)num;-(void)setName:(NSString *)name;-(void)setSpeed:(float)speed;-(int)num;-(NSString *)name;-(float)speed;@end@implementation Car-(void)setNum:(int)num{        _num = num;    }-(void)setName:(NSString *)name{        _name = name;    }-(void)setSpeed:(float)speed{        _speed = speed;    }-(int)num{        return _num;    }-(NSString *)name{    return _name;    }-(float)speed{    return _speed;    }@endint main(int argc, const char * argv[]) {    @autoreleasepool {                Plane *p = [Plane new];        p.name = @"c919";        [p start];        Car *c = [Car new];            }    return 0;}

此处,我们没有加任何访问修饰符,可以看到,在main函数中,对象c是无法访问其实例变量的,因为此处系统默认所有的实例变量为@protected的,也就是部分私有,只允许其自身及子类/派生类调用,外部函数同样不可调用。


如果我们将实例变量用@public修饰,实例变量已经可以访问。此处的@public的作用就是,让在有对象的前提下,所有位置都可以直接访问


@private修饰的实例变量,为私有变量,只能在定义的对象方法中对对象进行访问,子类中同样不可以访问

@package修的实例变量,只要处于同一个框架中就可以直接通 过变量名访问


三、私有方法

OC中私有方法实现有两种方式: 

1.方法在.m中实现,不在.h中声明(相对私有) 

2.通过匿名类别(延展)实现私有(一般意义上的私有)

我们还是在Plane中试验,代码如下:

只是在.m文件中实现一个方法


#import "Plane.h"@implementation Plane-(void)start{        NSLog(@"飞机起飞");    }-(void)privateTest{        NSLog(@"这是一个私有方法");    }@end

在main.h中,对象p调用其方法不仅不提示而且会报错

我们在Plane.m中调用定义的方法,如果调用成功,p在调用start方法时,会打印我们定义的字符串

@implementation Plane-(void)start{        NSLog(@"飞机起飞");    [self privateTest];    }-(void)privateTest{        NSLog(@"这是一个私有方法");    }@end

运行结果:飞机起飞

  这是一个私有方法

0 0
原创粉丝点击