OC学习_3_关于封装

=====文档变更状态====
2015-12-14:发布
2015-12-15:
1>setter、getter点语法的条件补充用【补1-S】【补1-E】标记开始和结束
2>增加了关于super和self的一些朴素介绍用【补2-S】【补2-E】标记开始和结束

=================
day03_2015-12-14
一、变长参数
1.使用C语言的stdarg.h库
A.va_list类型
B.va_start、va_arg、va_end函数
2.没有结束判断,需要自己在代码中进行,一般通过在参数末尾增加一个与有效参数无关的标志来实现结束判断
3.不仅函数,方法也可以接收变长参数
// 一个例子

#import <Foundation/Foundation.h>
@implementation VarParam:NSObject

+(int)getMax:(int)a,...{
int temp=a;
// 1.定义一个指针用于指向变长参数
va_list vp;
// 2.开始获取变长参数位置

va_start(vp, a);
// 3.获取第一个变长参数的值
int n=va_arg(vp, int);
// 4.循环判断
while (n!=INT_MIN) {// 如果写成while(n)则n为0时结束那么
                  // 此函数不能读入0
// 比如 int max =[VarParam getMax(-10,-30,0,25)读取会出问题]
        if (n>temp) {
            temp=n;
        }
        n=va_arg(vp, int);
    }
    va_end(vp);
    return temp;
}
@end

int getMin(int a,...){
    int temp=a;
    va_list vp;
    va_start(vp, a);
    int n=va_arg(vp, int);
    while (n!=INT_MAX) {
        if (n<temp) {
            temp=n;
        }
        n=va_arg(vp, int);
    }
    va_end(vp);
    return temp;
}
int main_var_param(){
    int max=[VarParam getMax:-35,10,0,20,23,12,34,INT_MIN];//-2^31
    NSLog(@"max=%d",max);
    int min=getMin(10,20,34,-34,-23,-12,INT_MAX);
    NSLog(@"min=%d",min);
    return 0;
}
//变长参数结束的标志的解决方式:<c的库stdarg.h的缺陷导致要解决判断参数的个数问题>
//1.是通过在参数的末尾放一个标记
// 2.类似于printf用占位符标记参数的个数
// 3.第一个参数用于标记参数的个数

二、封装
1.解决数据的有效性(合法又合理)、读写性
2.成员变量的默认权限:
在接口部分是保护的:@protected
在实现部分是私有的:@private
3.封装步骤
A.成员变量私有化;
B.声明相应的getter和setter
C.给出getter和setter的实现
4.getter:除BOOL类型外,方法名与要封装的成员变量同名,有返回值(与封装的成员变量相同)无参数;BOOL类型使用is开头加上要封装的成员变量名作为方法名
5.setter:使用set开头加上要封装的成员变量名作为方法名,无返回值有参数(类型与要封装的成员变量相同);在setter中通过代码控制数据的有效性
6.如果只提供getter不提供setter,即为只读性
7.BOOL类型:getter方法名使用is开头
8.NSString类型:setter中一般调用参数的copy方法赋值

// person

//  YYPerson.h
#import <Foundation/Foundation.h>

@interface YYPerson : NSObject
{
@private
    int _age;
    char _gender;//M F
NSString* name;
BOOL married;

}
-(int)age;
-(void)setAge:(int)age;

-(char)gender;
-(void)setGender:(char)gender;

-(void)setName:(NSString *)name;
-(NSString *)name;

-(void)setMarried:(BOOL)married;
-(BOOL)isMarried;



@end
//  YYPerson.m
#import "YYPerson.h"

@implementation YYPerson
-(int)age{
    return _age;
}

-(void)setAge:(int)age{
    if (age<0 || age>150) {
        _age=20;
    }
    else{
        _age=age;
    }
}

-(char)gender{
    return _gender;
}

-(void)setGender:(char)gender{
//    if (gender=='M' || gender=='F') {
//        _gender=gender;
//    }
//    else{
//        _gender='M';
//    }
        if (gender!='M' && gender!='F') {
            _gender='M';
        }
        else{
            _gender=gender;
        }
}

// NSString 类型setter要用copy
-(void)setName:(NSString *)name
{

    _name = [name copy];

}
-(NSString *)name
{
    return _name;
} 


// 注意BOOL类型setter、getter方法的写法
// 是想保证_married 必须被赋予NO或YES 值而不是传进来的数// 字 比如传进来10则_married被赋值为YES
//  getter方法要以is开头
-(void)setMarried:(BOOL)married
{
    if (married == NO)
    {
        _married = NO;
    }
    else
    {
        _married = YES;
    }

}
-(BOOL)isMarried
{
    return _married;
}

-(void)
@end
//  test_person.m
#import "YYPerson.h"
int main(){

    XBPerson *per = [[XBPerson alloc] init];
    [per setAge:20];
    [per setName:@"mike"];
    [per setMarried:10];
// 规范的点调用<这里的规范指的是方法名>
NSLog(@"name:%@,married:%d",per.name,per.isMarried);
// 不规范的点调用<这里的不规范指的是方法名aaMarried>
NSLog(@"name:%@,married:%d",per.name,per.aaMarried);
// 综上点的调用,点语法只是告诉编译器我要调用方法,至于调用
//哪个方法由用法指定,系统默认调用的是规范的setter,getter方法
// 点语法还可以访问其它非属性方法即非settter getter方法【补1—S】只能调用不带参数只有返回值的方法【补1-E】
    return 0;
}

// 注意
1>NSString 的setter方法要用copy
2>BOOL类型的setter、getter方法的写法
3>点语法的本质
4>当点语法与BOOL类型混在一起时:如下
@property (nonatomic,assign,getter=isMan) int man;
则在main方法使用的时候,即可以用:
a>  对象名.man 和对象名.isMan 
b>  [对象名 isMan]不能用[对象名 man],
综上:<点语法调用方法比普通方法调用多一个功能【补1-S】但这种功能只是限制在能调用不带参数的非getter setter方法【补1-E】>
通过点语法可以访问改名前的方法而通过[对象 方法名]则不能

三、封装之self关键字
1.区别同名的成员变量和局部变量(包括参数):仅在对象方法中可以使用
在对象方法中,如果成员变量已经规范封装,可以使用self.成员变量的形式访问
在对象方法中如果需要访问其它对象方法,可以使用[self 其它对象方法]的形式访问
2.调用类中其它方法:对象方法中调用其它对象方法,类方法中调用其它的类方法
在类方法中,代表当前类,可以使用[self 其它类方法名]的形式访问类方法,但无法直接访问
其它对象方法、成员变量
// YYPersonPro

//  YYPersonPro.h
#import <Foundation/Foundation.h>

@interface YYPersonPro : NSObject
{
    //默认是保护权限,子类中可以直接访问
    int prot;
@private
    int age;
    char _gender;//M F
    NSString* _name;
}
-(int)age;
-(void)setAge:(int)age;

-(char)gender;
-(void)setGender:(char)gender;

-(NSString*)name;
-(void)setName:(NSString*)name;

+(void)classMethod1;
+(void)classMethod2;

-(void)say;
-(void)eat:(NSString*)food;
@end

//  YYPersonPro.m
#import "YYPersonPro.h"

@implementation YYPersonPro

+(void)classMethod1{
    NSLog(@"class method 1");
    [self classMethod2];
}

+(void)classMethod2{
    NSLog(@"class method 2");
    //类方法中不能使用self调用对象方法
//    [self setAge:10];
}
-(NSString *)name{
    return _name;
}

-(void)setName:(NSString *)name{
    _name=[name copy];
//    [self setAge:10];
    //对象方法中不能使用self调用类方法
//    [self classMethod1];
}

-(int)age{
    return age;
}

-(void)setAge:(int)age{
    if (age<0 || age>150) {
        self->age=20;
    }
    else{
        self->age=age;
    }
}

-(char)gender{
    return _gender;
}

-(void)setGender:(char)gender{
    if (gender!='M' && gender!='F') {
        _gender='M';
    }
    else{
        _gender=gender;
    }
}

-(void)say{
    NSLog(@"I am %@,age is %d,gender is %c.",_name,age,_gender);
}

-(void)eat:(NSString *)food{
    NSLog(@"Person %@ is eatting %@.",_name,food);
}
@end

//  test1.m
#import "YYPersonPro.h"
int main_pp(){
    YYPersonPro* per=[YYPersonPro new];
    [per setAge:10];
    NSLog(@"age:%d",[per age]);//0
    return 0;
}



四、继承inheritance
1.继承的语法:@interface 子类名:父类名
2.继承的作用:减少代码冗余,子类可以拥有父类的所有,还可以增加新的内容
3.注意:继承要符合“is a”关系,不能仅仅为了减少代码冗余而去继承
4.访问权限
@private @protected @public
本类中 可以 可以 可以
子类中 不可以 可以 可以
类外 不可以 不可以 可以
另外还有@package(软件包)权限
5.关于同名:
A.子类中不允许出现与父类同名的成员变量
B.子类中可以有与父类同名的方法,在调用时通过super和self区别;如果方法与父类同名,可以省略声明部分
【补2-S】
关于super和self特点的唐僧解释1
super关键字:用于访问父类中与子类同名的方法;如果子类中有与父类同名的方法,使用self和super效果不同;如果子类中没有与父类同名的方法,使用self和super效果相同;
关于super和self特点的唐僧解释2
如果子类中有与父类同名的方法(即重写)则在一个方法中[self 方法名]和[super 方法名(重写后)]调用的是不同的方法(前者调用重写前后者调用重写后),但是如果没有重写方法则 [super 方法名]和[self 方法名]调用的是同一个方法,这种现象的原因在于:用户调用方法时,系统始终是从当前类里找方法,如果没找到然后再到父类中找
【补2-E】
// YYTeacher

//  YYTeacher.h
#import "YYPersonPro.h"

@interface YYTeacher : YYPersonPro
{
@private
    //子类中不允许出现与父类同名的成员变量
    //int age;
    int _salary;
    NSString* _course;
}
-(int)salary;
-(NSString*)course;
-(void)setSalary:(int)salary;
-(void)setCourse:(NSString*)course;
-(void)teacherSay;
//子类中可以有与父类同名的方法,在调用时通过super和self区别
//如果方法与父类同名,可以省略声明部分
//-(void)say;
@end
//  YYTeacher.m
#import "YYTeacher.h"

@implementation YYTeacher
-(int)salary{
    return _salary;
}

-(NSString *)course{
    return _course;
}

-(void)setSalary:(int)salary{
    if (salary<0) {
        _salary=0;
    }
    else{
        _salary=salary;
    }
}

-(void)setCourse:(NSString *)course{
    _course=[course copy];
}
-(void)say{
    NSLog(@"YYTeacher say!");
}

-(void)teacherSay{
//    [super say];
    NSLog(@"I am teacher %@,age is %d,gender is %c,teaching %@,my salary is %d.",[super name],[super age],[super gender],self->_course,self->_salary);
}
-(void)eat:(NSString *)food{
    NSLog(@"Teacher %@ is eatting %@",[self name],food);
}
@end

//  test_teacher.m
#import "YYTeacher.h"
int main_inher(){
    YYTeacher* tom=[YYTeacher new];
    [tom setName:@"Tom"];
    [tom setAge:40];
    [tom setGender:'f'];
    [tom setSalary:33300];
    [tom setCourse:@"iOS"];
    NSLog(@"gender:%c",[tom gender]);//M
    NSLog(@"salary:%d",[tom salary]);//0
    [tom teacherSay];
    [tom say];
    return 0;
}

=================EOF===============

内容概要:本文详细介绍了扫描单分子定位显微镜(scanSMLM)技术及其在三维超分辨体积成像中的应用。scanSMLM通过电调透镜(ETL)实现快速轴向扫描,结合4f检测系统将不同焦平面的荧光信号聚焦到固定成像面,从而实现快速、大视场的三维超分辨成像。文章不仅涵盖了系统硬件的设计与实现,还提供了详细的软件代码实现,包括ETL控制、3D样本模拟、体积扫描、单分子定位、3D重建和分子聚类分析等功能。此外,文章还比较了循环扫描与常规扫描模式,展示了前者在光漂白效应上的优势,并通过荧光珠校准、肌动蛋白丝、线粒体网络和流感A病毒血凝素(HA)蛋白聚类的三维成像实验,验证了系统的性能和应用潜力。最后,文章深入探讨了HA蛋白聚类与病毒感染的关系,模拟了24小时内HA聚类的动态变化,提供了从分子到细胞尺度的多尺度分析能力。 适合人群:具备生物学、物理学或工程学背景,对超分辨显微成像技术感兴趣的科研人员,尤其是从细胞生物学、病毒学或光学成像研究的科学家和技术人员。 使用场景及目标:①理解和掌握scanSMLM技术的工作原理及其在三维超分辨成像中的应用;②学习如何通过Python代码实现完整的scanSMLM系统,包括硬件控制、图像采集、3D重建和数据分析;③应用于单分子水平研究细胞内结构和动态过程,如病毒入侵机制、蛋白质聚类等。 其他说明:本文提供的代码不仅实现了scanSMLM系统的完整工作流程,还涵盖了多种超分辨成像技术的模拟和比较,如STED、GSDIM等。此外,文章还强调了系统在硬件改动小、成像速度快等方面的优势,为研究人员提供了从理论到实践的全面指导。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值