做C#、Java的人都知道private、protect、public这些访问权限,在OC中看项目基本都没用到这些,昨天就好奇的仔细了解了下,其实OC中也是有这些访问权限的修饰。说实话有好多做过编程的也未必对这些基础知识了解。
1.分清属性和变量的区别
属性是对变量的封装,可以通过属性(get\set)方法来访问变量。例如有一些变量(例如年龄、性别等)在赋值或取值要满足一些条件,那如何解决呢? 于是属性就应运而生,用它的get、set方法来解决这个问题 ,这也是面向对象中封装的体现。
2.private、protect、public访问权限修饰符
这些修饰符可以对变量、属性、方法进行修饰。为什么会出现这些修饰符呢?比如一些信息是隐私的不希望被外部访问或者访问也只能它家族里可以访问,所以权限修饰符应运而生。
3.OC中的private、protect、public访问权限修饰符
看别人的项目包括自己的项目都没有对属性、方法、变量的修饰符。其实oc中也是有这些的,只是不常用或者根本甚至根本没用过。
属性访问权限
protected 该类和所有的子类中的方法可以直接访问这样的变量,这是默认的。
private 该类中的方法可以访问这样的变量,子类不可以 可以将变量放在.m中
public 除了自己和子类中的方法外,也可以被其他类或者其他模块中的方法所访问。开放性最大。
package 框架集中
方法访问权限
只有public、private public .h文件 private .m中
4.代码demo
下面定义了一个父类Student,子类OldStudent继承父类Student。
#import <Foundation/Foundation.h>
@interface Student : NSObject
{
int age; //年龄 默认protect
@public
int no; // 学号
@protected
float height; // 身高
@private
float weight; // 体重
}
//@property @synthesize
@property(nonatomic,assign,readwrite) int No;
@property(nonatomic,assign,readwrite) float Weight;
@property(nonatomic,assign,readwrite) float Height;
//get/set方法
-(void)setAge:(int)newAge;
-(int) Age;
-(void) eat;
@end
#import "Student.h"
#import <objc/runtime.h>
@implementation Student
@synthesize Weight=weight,Height=height;
-(void)setAge:(int)newAge
{
if (age!=newAge) {
age=newAge;
}
}
-(int) Age
{
return age;
}
-(void) eat
{
NSLog(@"eat");
[self goToSchool];
}
-(void) goToSchool
{
NSLog(@"goToSchool");
}
@end
#import "Student.h"
@interface OldStudent : Student
@property (nonatomic,strong) NSString *Major;//专业
@end
#import "OldStudent.h"
@implementation OldStudent
- (instancetype)init
{
self = [super init];
if (self) {
height=172.0; //protect
no=0; //public
age=18; //protect
_Major=@"计算机"; //默认 protect
}
return self;
}
-(void)eat
{
NSLog(@"eat.......");
}
@end
在上面OldStudent中并不能直接访问Student中的Weight。
#import <Foundation/Foundation.h>
#import "Student.h"
#import "OldStudent.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *student=[[Student alloc]init];
//访问变量
student->no=150001;
//访问属性
student.Age=23;
student.Height=170.0;
student.Weight=170.0;
[student eat];
NSLog(@"Age=%d No=%d",student.Age,student->no);
OldStudent *oldStudent=[[OldStudent alloc]init];
oldStudent->no=15002;
// oldStudent->age=24; //protect 子类不能继承 只能通过父类get/set方法
oldStudent.Age=24;
oldStudent.Weight=200.0;
oldStudent.Major=@"软件"; //默认是protect
[oldStudent eat];
NSLog(@"Age=%d No=%d",oldStudent.Age,oldStudent->no);
}
return 0;
}
上面的代码中看到可以通过类似C++中->来访问变量。OldStudent不能直接访问age变量,可以通过属性来访问。
这篇主要理解继承封装,对于多态,oc中的多态和C#的还不太一样,oc是没有编译时多态,是通过消息转发来完成,之前博客也有写。