- 新建一个XCode项目
- 新建一个类
1、成员变量、属性
1.1、类内使用成员变量,类外使用属性
Role.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Role : NSObject
{
//成员变量:只能类内使用
NSString *_name;
int _age;
}
//属性:类外可使用
//属性就是内部成员变量的外部接口
@property (nonatomic, strong) NSString *name;
//属性也相当于 get/set 方法
-(void)setAge:(int)age;
-(int)getAge;
-(void)display;
@end
NS_ASSUME_NONNULL_END
Role.m
#import "Role.h"
@implementation Role
//绑定属性和成员变量
//推荐使用成原变量与属性不同命的方式,成员变量前面加_,属性不加
@synthesize name = _name;
//构造方法
- (instancetype)init
{
self = [super init];
if (self) {
//类内调用的都是成员变量
_name = @"";
_age = 0;
}
return self;
}
-(void)setAge:(int)age{
_age = age;
}
-(int)getAge{
return _age;
}
-(void)display{
NSLog(@"角色名称: %@ 角色年龄: %d", _name, _age);
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Role.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//实例化对象(* 代表指针)
//[类名 方法名]
//[对象名 方法名]
//alloc:为对象分配内存空间
//init:初始化操
Role *r1 = [[Role alloc]init];
[r1 display]; //角色名称: 角色年龄: 0
[r1 setName:@"琦玉"];
[r1 setAge:20];
[r1 display]; //角色名称: 琦玉 角色年龄: 20
//属性可以直接当做get/set用
r1.name = @"杰诺斯";
NSLog(@"角色名称: %@", r1.name); //角色名称: 杰诺斯
}
return 0;
}
1.2、补充
Role2.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Role2 : NSObject
//新版本中只需声明 属性,便会自动生成 对应的成员变量(如属性 name,便会自动生成成员变量 _name)
@property (nonatomic, strong) NSString *name;
@property () int age;
-(void)display;
-(void)setSex:(NSString *)sex;
-(NSString *)getSex;
@end
NS_ASSUME_NONNULL_END
Role2.m
#import "Role2.h"
@implementation Role2
//新版xCode可以在 .m 文件中声明成员变量
{
NSString *_sex;
}
- (instancetype)init
{
self = [super init];
if (self) {
_name = @"";
_age = 0;
_sex = @"";
}
return self;
}
-(void)display{
NSLog(@"角色名称: %@ 角色年龄: %d 角色性别: %@", _name, _age, _sex);
}
-(void)setSex:(NSString *)sex{
_sex = sex;
}
-(NSString*)getSex{
return _sex;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Role2.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Role2 *r2 = [[Role2 alloc]init];
r2.name = @"地狱吹雪";
r2.age = 26;
[r2 setSex:@"女"];
[r2 display]; //角色名称: 地狱吹雪 角色年龄: 26 角色性别: 女
}
return 0;
}
2、方法
2.1、对象方法、类方法
Role3.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Role3 : NSObject
// - 代表对象方法,用对象名调用
-(void)setName:(NSString*)name;
-(NSString*)getName;
-(void)objectFun:(NSString*)name andCom:(NSString*)company;
-(void)objectReport;
// + 代表类方法,用类名调用
+(void)setCompany:(NSString*)company;
+(NSString*)getCompany;
+(void)classFun:(NSString*)name andCom:(NSString*)company;
+(void)classReport;
//初始化方法,重写init
//对于初始化方法,id和instancetype没有区别
//对于其他方法,填id可能会导致类型错误
//instancetype代表当前类的类型,当前类型是 Role3,那么instancetype就是Role3类型
-(instancetype)init;
//id可以代表任意类型,无需指定特定类型
-(id)init2;
//自定义构造方法
-(id)initWithName:(NSString*)name andCompany:(NSString*)company;
@end
NS_ASSUME_NONNULL_END
Role3.m
#import "Role3.h"
@implementation Role3
{
NSString *_name;
}
//静态变量
static NSString *_company;
-(void)setName:(NSString *)name{
_name = name;
}
-(NSString*)getName{
return _name;
}
-(void)objectFun:(NSString *)name andCom:(NSString *)company{
//对象方法中,可以使用成员变量、静态变量
_name = name;
_company = company;
}
-(void)objectReport{
NSLog(@"对象方法objectReport--- 角色名称:%@ 角色公司: %@", _name, _company);
//对象方法中调类方法,防止循环调用,暂时注释掉
// [Role3 classReport];
}
+(void)setCompany:(NSString *)company{
_company = company;
}
+(NSString*)getCompany{
return _company;
}
+(void)classFun:(NSString *)name andCom:(NSString *)company{
//类方法中只能调用静态变量
_company = company;
}
+(void)classReport{
NSLog(@"类方法classReport --- 角色公司: %@", _company);
//类方法中调对象方法,防止循环调用,暂时注释掉
// [[Role3 alloc]objectReport];
}
-(instancetype)init{
self = [super init];
if (self) {
_name = @"name";
_company = @"company";
}
return self;
}
-(id)init2{
self = [super init];
if (self) {
_name = @"name2";
_company = @"company2";
}
return self;
}
-(id)initWithName:(NSString *)name andCompany:(NSString *)company{
self = [super init];
if (self) {
_name = name;
_company = company;
}
return self;
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Role3.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Role3 *r31 = [[Role3 alloc]init];
[r31 objectReport]; //对象方法objectReport--- 角色名称:name 角色公司: company
Role3 *r32 = [[Role3 alloc]init2];
[r32 objectReport]; //对象方法objectReport--- 角色名称:name2 角色公司: company2
Role3 *r33 = [[Role3 alloc]initWithName:@"战栗龙卷" andCompany:@"英雄协会"];
[r33 objectReport]; //对象方法objectReport--- 角色名称:战栗龙卷 角色公司: 英雄协会
[r33 objectFun:@"饿狼" andCom:@"怪人协会"];
[r33 objectReport]; //对象方法objectReport--- 角色名称:饿狼 角色公司: 怪人协会
[Role3 classReport]; //类方法classReport --- 角色公司: 怪人协会
[Role3 classFun:@"邦古" andCom:@"英雄协会"];
[Role3 classReport]; //类方法classReport --- 角色公司: 英雄协会
[r33 objectReport]; //对象方法objectReport--- 角色名称:饿狼 角色公司: 英雄协会
}
return 0;
}
2.2、补充:访问修饰复符
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MyClass : NSObject
{
//成员变量访问修饰复符
//@public,类内类外均可使用
//@private,类内可用,类外不可用,不可继承
//@protected,默认为受保护的,类内可用,类外不可用,可继承
//@package,框架权限,在框架内相当于受保护,在框架外相当于私有(常用于写三方库)
@public
int _classInt;
}
//属性实质上是set和get方法,而不是把成员变量便为公有
@property(nonatomic,strong)NSString *className;
//方法没有访问修饰符
- (void)report;
@end
NS_ASSUME_NONNULL_END
3、继承、多态
- 多态:方法重写,方法重载(函数名相同,参数不同)
- OC中不支持方法重载
Animal.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Animal : NSObject
{
@protected
NSString* _category;
}
@property (nonatomic, strong) NSString* category;
-(instancetype)initWithCategory:(NSString*)category;
-(void) howl;
@end
NS_ASSUME_NONNULL_END
Animal.m
#import "Animal.h"
@implementation Animal
@synthesize category = _category;
-(instancetype)initWithCategory:(NSString *)category{
self = [super init];
if (self) {
_category = @"动物";
}
return self;
}
-(void)howl{
NSLog(@"我是%@, 我会叫", _category);
}
@end
Dog.h
#import "Animal.h"
NS_ASSUME_NONNULL_BEGIN
@interface Dog : Animal
@end
NS_ASSUME_NONNULL_END
Dog.m
#import "Dog.h"
@implementation Dog
//方法重写
-(instancetype)initWithCategory:(NSString *)category{
self = [super init];
if (self) {
_category = category;
}
return self;
}
//方法重写
- (void)howl{
NSLog(@"我是%@, 汪汪汪", _category);
}
@end
main.m
#import <Foundation/Foundation.h>
//Dog.h 中已经引用了Animal.h,所以此处可以不写Animal.h的引用
#import "Dog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Animal *animal = [[Animal alloc]initWithCategory:@"动物"];
[animal howl]; //我是动物, 我会叫
Dog *dog = [[Dog alloc]initWithCategory:@"狗"];
[dog howl]; //我是狗, 汪汪汪
}
return 0;
}