OC学习之道–类的三大特性

编程 AnthonyZhai 8个月前 (03-26) 290次浏览 已收录 0个评论 扫描二维码

类的封装

OC类中的成员变量是可以用权限修饰符private、protected、public、package
public即共有,其子类和外部类都可以直接访问。
private即私有,只能被本类访问。
protected即受保护,能被本类及子类访问,没有权限修饰符时默认protected
package即框架(包),这个和Java有点儿不一样,不是指同一包里都可以访问,而是框架级的访问权限。
部分代码如下:

#ifndef Animals_H
#define Animals_H
#import <Foundation/Foundation.h>
@interface Animals : NSObject{
@public
    NSString* _Color;
    NSInteger _Age;
}
- (void)setColor:(NSString*) Color;
- (void)setAge:(NSInteger) Age;
- (NSString*)Color;
- (NSInteger)Age;
- (void)Eat;
- (void)Run;
- (void)Sleep;
- (void)Print;
- (id)initWithAge:(NSInteger)Age :(NSString*)Color;
@end
#endif

其实,在OC中还为我们提供了属性@property。在@interface{}之后,@end之前,定义属性的格式如下:
@property (参数) 类型 属性名
参数在这里不讨论,之后另写一篇与本句相同的写法还有“成员变量+@property+@synthesize”形式,都可以达到有些成员变量需要被其他类有限制的访问的要求,而且可以减轻程序员的负担,即能够自动生成成员变量或属性对应的getter和setter方法,且会在.m文件中生成对应的_属性名的变量。
除此之外,还可以使用点语法,其他类使用“类名+属性名”访问。代码如下:

#import <Foundation/Foundation.h>
#import "Animals.h"
@interface Person : NSObject{ 
}
@property (nonatomic,strong) NSString* Name;
- (void)Feed:(Animals*)Animal;
@end

OC类中的对象方法也有public和private之分,public方法在.h文件中声明,私有方法在.m文件中直接实现即可。代码如下:

@implementation Person
- (void)Feed:(Animals *)Animal{
    [Animal Eat];
}
- (void)Print{
    NSLog(@"我叫%@",_Name);
}
@end

可以看到以上两个代码分为是类的声明.h和类的实现.m,然而在类的实现中使用到_Name变量,但是我之前并没有声明这个变量,这是因为在类的声明里有Name属性的声明,会自动在类的实现中生成上述变量。

类的继承及多态

上节说到OC中不支持多重继承,有了继承才可以谈及多态。类图如下所示:
OmniGraffle导出类图
在继承中需要注意:
1、父类中所有成员变量都会被继承到子类中,甚至是private变量,只是不能被子类访问而已。因此要考虑到子类对象的大小一定大于等于父类对象的大小。
2、子类不可以重新定义与父类中名称一样的变量。
3、子类可以重写(override)父类的方法。
4、当调用子类方法时,优先在子类中寻找,若找不到则转向其父类寻找相应的方法。
在多态中需要注意:
1、多以实现父类的指针指向其子类对象。这是实现多态重要的一步。
2、父类不能调用直接调用子类中特有方法,非要使用时要采用强制类型转换。
代码如下:

#import <Foundation/Foundation.h>
#import "Dog.h"
#import "Cat.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
    Animals* Animal=[[Dog alloc]initWithName:@"小黄" Age:5 Color:@"黄" Variety:@"中华田园犬"];
    [Animal Print];
    
    Person* Anthony=[[Person alloc]init];
    Anthony.Name=@"翟天亨。";
    NSLog(@"我叫%@",Anthony.Name);
    [Anthony Feed:Animal];
    /*Animal指针是不能调用子类的方法,即无法完成 Animal.Name=@"小黄";
    要想使用则需要进行强制类型转换,即 Dog* dog=(Dog*)Animal;
     */
    /*
    Dog* dog=[[Dog alloc]initWithName:@"小黑" Age:2 Color:@"黑白相间" Variety:@"泰迪"];
    [dog Print];
    dog.Name=@"小黑";
    dog.Variety=@"中华田园犬";
    [dog Print];
    注意到这里的注释,要想使用点语法,必须单独为成员变量设置setter方法和getter方法
     */
    Animal=[[Cat alloc]initWithAge:3 Color:@"白"];
    [Animal Print];
    [Anthony Feed:Animal];
    return 0;
}

实验结果如下所示:
实验结果
OCthings/tree/master/Animals" target="_blank" rel="nofollow">GitHub地址

Objective-C学习之道系列文章列表如下:


“最初的梦想”版权所有丨如未注明 , 均为原创丨若有侵权,请邮件联系留言给我
转载请注明原文链接: OC学习之道–类的三大特性
喜欢 (1)
[使用支付宝或微信扫码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址