一,
关于OC的实例变量的可见度,即实例变量的访问权限有三种:
1),@public 公有的
被@public修饰的实例变量是公共的,即没有访问权限,在任何文件中都可以访问,(访问方式是通过对象+指向操作符)
2),@protected 受保护的
被@protected修饰的实例变量有一定的访问限,只允许在本类文件及子类文件中访问,其他文件不可访问
3),@private 私有的
被@private 修饰的实例变量,只允在在本类文件中访问,不可以在子类文件以及其他文件中访问.
这里可以说下私有方法;私有方法即没有在.h文件中声明,之间在.m文件中实现的方法,它只允许本类调用,外部无法访问,即使是子类也无法访问
二,
我们通常在定义实例变量的时候一般都不再声明变量的访问权限,OC默认的是@protected,因为OC面向对象的三大特性:封装,继承,多态.如果声明为public外部就可以访问以及修改会影响内部的一个实现,暴漏实现细节,不能体现OC面向对象的封装特性(封装的思想是隐藏内部的实现).如果声明为private,子类文件就不可以访问该实例变量,这样子类文件需重新定义声明,这样违背了OC面向对象的继承特性,(继承是指父类的所有实例变量和方法等子类都可以访问使用.
当定义为protected又需要对该变量重新赋值时,可以利用设置器,即setter方法针对每个实例变量设置一个方法为它赋值,同时利用访问器,即getter方法针对每个实例变量设置一个方法来获取它的值
如:举个人这个类的例子 类名为Person
其实例变量为:
{
NSString *_name; //姓名
NSString *_sex; //性别
NSInteger _age; //年龄
}
1,设置器,getter方法
1)为_name赋值
- (void)setName:(NSString*)name;
2)为_sex赋值
- (void)setSex:(NSString*)sex;
3)为_age赋值
-(void)setAge:(NSInteger)age;
2,访问器 getter方法
1)读取_name的值
- (NSString *)name;
2)读取_sex的值
- (NSString *)sex;
3)读取_age的值
- (NSInteger)age;
三,
类的继承
1,当多个类出现部分相同的实例变量和方法时就要考虑用继承, 继承时将多个类中相同的实例变量的方法提出来写成一个公共的父类.
子类继承父类: 会将父类中除了声明为@private的实例变量以及私有方法外,其余内容都会被继承们所有如果子类中有和父类同样的内容,可以全部删除.
私有方法 :即没在.h文件中声明,只在,m文件中实现了该方法,对于私有方法不允许外部访问,只能让本类调用访问
一个类继承另一个类时要在.h文件的@interface开头地方把它的父类写在:号后面如,一个学生类Student继承了Person类
@interface Student:Person
2,继承时方法存在三种:
1),保留父类对该方法的实现,(实现方法不重写)
2),按子类重写后的方式来实现(实现方式重写方法,写自己的实现体完全忽略父类的实现)
3),对于该方法既有父类的方法实现也有子类对该方法的实现,在这种情况下我们一般在方法的实现内容里先把调用父类方法的实现即用[super (方法)]这个方法名是就是继承过来的方法名,然后再实现子类特有的行为
3,这里需要重点说一下继承类时自定义初始化的实现方法
首先自定义初始化的方法名必须是init+Whith开头,返回值是(id),是”-”号方法,
当子类有独有的实例变量时如:
{
NSString *_num;
NSString *_course;
}
多了一个学号和课程,初始化时子类只对自己独有的实例变量赋值即可,super调用父类对初始化方法的实现,为从父类继承过来的实例变量赋值,这里的self还是调用方法时的值返回给自己,谁调用就返回给谁,如果赋值不成功即self == nil,这时子类不在赋值,因为如果父类的实例变量赋值失败了,子类的赋值也就毫无意义了
-(id)initWithname:(NSString*)name sex:(NSString *)sex age:(NSInteger)age num:(NSString *)numcourse:(NSString *)course
{
self = [super initWithname:name sex:sexage:age];
if(self != nil) {
_course= course;
_num= num;
}
return self;
}
四,便利构造器
我们在main函数里创建对象接收消息时往往在创建对象时需要给对象开辟空间和初始化,这样可能比较麻烦, 我们在定义类的时候直接实现为对象开辟空间,即便利构造器
作用:快速创建对象,内部封装了创建对象的过程,
格式: 1. +号方法,
2, 返回值为id类型,
3, 以类名+With开头,拼接上多个参数
还以上述学生类Student类继承人类Person为例
1)在.h文件里写方法的声明,
在这里该方法为”+”号方法
+ (id)studentWithname:(NSString *)name sex:(NSString*)sex age:(NSInteger)age num:(NSString *)num course:(NSString *)course;
2)在.m文件里写方法的实现
+ (id)studentWithname:(NSString *)name sex:(NSString*)sex age:(NSInteger)age num:(NSString *)num course:(NSString *)course
{
return [[Studentalloc] initWithname:name sex:sex age:age num:num course:course];
}
五,
类的循环调用的有关问题
该问题一般用于解决一个类实例变量里需要用到另一个类的所有变量
例如一个家庭类,成员有爸爸,妈妈,儿子,这三个类建立每个都需要另一个类的内容如爸爸类实例变量有姓名年龄,妻子,儿子. 这里妻子和儿子的类型就是妻子类和儿子类的类名 + * ,这时要循环调用,在遇到循环调用时需要导入文件,但是这里的导入文件不能直接在该类的.h文件用”#import “头文件”” 导入文件,因为这个类还没有定义,无法识别,再使用该类时不能把它当做一个类而所以在该类的.h文件里使用”@ class + 要调用的类名”,将要调用的类声明为一个字符串,但是它不具备的类的内容 ,所以要在该类的.m文件里用”#import“头文件””导入头文件.下面举个家庭的例子
1)男人类
(.h文件里)
@class Woman;
#import "Child.h"
@interface Man : NSObject
{
NSString*_name; //姓名
NSString*_sex; //性别
NSInteger_age; //年龄
Woman*_wife; //妻子
}
//设置妻子
- (void)setWife:(Woman *)wife;
//设置孩子
- (void)setChild:(Child *)baby;
//访问姓名
- (NSString *)name;
//为_sex赋值
- (void)setSex:(NSString *)sex;
//为_age赋值
- (void)setAge:(NSInteger)age;
- (id)initWithName:(NSString *)name Sex:(NSString*)sex Age:(NSInteger)age;
//输出一个人的信息
- (void)print;
@end
(.m文件里)
#import "Man.h"
#import "Woman.h"
@implementation Man
- (void)setWife:(Woman *)wife
{
_wife =wife;
}
- (void)setChild:(Child *)baby
{
_baby =baby;
}
//访问姓名
- (NSString *)name
{
return_name;
}
//为sex赋值
- (void)setSex:(NSString *)sex
{
_sex =sex;
}
//为age赋值
- (void)setAge:(NSInteger)age
{
_age =age;
}
- (id)initWithName:(NSString *)name Sex:(NSString*)sex Age:(NSInteger)age
{
_name =name;
_sex =sex;
_age =age;
returnself; }
-(void)print
{
NSLog(@"I am a man,My name is %@,My wife‘s name is %@, My baby‘sname is %@",_name,[_wife name],[_baby name]);
}
其中女人类和孩子类跟男人类相似,只是调用的类有所不同,这里不再赘述
原文地址:http://9178463.blog.51cto.com/9168463/1536560