@public @private @protected @package
1)@public (公開的)包含@protected的作用範圍;並且在有物件的前提下,任何地方都可以直接訪問。
(2)@protected (受保護的)只能在當前類和子類的物件方法中訪問(在@interface @end之間宣告的成員變數如果不做特別的說明,那麼其預設是protected的)
(3)@private (私有的)只能在當前類的物件方法中才能直接訪問(定義在m檔案中的類擴充套件部分或者是@implementation內)
(4)@package (框架級別的)作用域介於私有和公開之間,只要處於同一個框架中就可以直接通過變數名訪問
首先定義三個類,Person類,Children類,Animal類,其中Children類是Person類的子類。
Person類標頭檔案:
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
NSString *name;
@public int age;
@private float wegiht;
}
-(void)setName;
-(void)setAge;
-(void)setWegiht;
@end
Person類m檔案:
#import "Person.h"
//在當前類物件的方法中都能訪問之前定義的例項變數,無論是@private,@protected,還是@public
@implementation Person
-(void)setName {
NSLog(@"%@",name);
}
-(void)setAge {
age=20;
NSLog(@"%d",age);
}
-(void)setWegiht{
wegiht=50;
}
@end
接下來看Children類,也就是Person類子類的標頭檔案和m檔案
標頭檔案:
#import "Person.h"
@interface Children : Person
@end
m檔案:
#import "Children.h"
//由於name變數是@protected,age變數是@public,wegiht變數是@private ,所以Children類的物件方法中不能訪問wegiht變數,而可以訪問name變數和age變數
@implementation Children
-(void)setName {
[email protected]"small wall";
}
-(void)setAge {
age=8;
}
@end
如果訪問私有變數wegiht,則會報錯:
接下來看main檔案:
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Children.h"
#import "Animal.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
//由於age變數是@public,所以在有物件的前提下,是可以直接訪問,其他的變數是不可以直接訪問的
Person *xiaoming=[[Person alloc]init];
[xiaoming setAge];//此時age=20
xiaoming->age=24;//直接訪問public變數
NSLog(@"%d",xiaoming->age);
Children *baobao=[[Children alloc]init];
baobao->age=2;//直接訪問public變數
NSLog(@"%d",baobao->age);
}
return 0;
}
@interface部分為類擴充套件(extension)。
其被設計出來就是為了解決兩個問題的,
其一,定義類私有方法的地方。
其二,實現public readonly,private readwrite的property(意思是在h標頭檔案中定義一個屬性對外是readonly的,但在類的內部希望是可讀寫的,所以可以在m原始檔中的@interface部分重新定義此屬性為readwrite,此時此屬性對外是隻讀的,對內是讀寫的),雖然是這麼說但是實測在xcode10上h標頭檔案中定義一個屬性對外是readonly的,.m裡面的方法還是可以,原因是自定義了set方法,所以沒問題,沒的話確實報錯。
此外,也可在此部分申明變數和屬性,但申明的變數,屬性和方法均為私有的,只能夠被當前類訪問,相當於private。
原文:https://blog.csdn.net/chokshen/article/details/52944648