面向对象4

对象初始化

[[class alloc] init] 中alloc负责为实例变量分配内存病将内存空间重置为0,init则初始化对象

多个自定义动态初始化方法:

#import "MyCar.h"
@implementation MyCar
@snythesize brand = _brand;
@snythesize model = _model;
@synthesize color = _coor;
//重写 init 初始化方法
- (void) init
{
    //调用父类的 init 方法初始化对象病赋予self
    //当 self 不为 nil 时,表示初始化成功,可继续
    if(self = [super init])
    {
        self.brand = @"奥迪"self.model = @"Q5";
        self.color = @"黑色";
    }
    return self;
}
//自定义初始化方法
- (void) initWithBrand:(NSString*) brand model:(NSString*) model
{
    if(self = [super init])
    {
        self.brand = brand;
        self.model = model;
        self.color = @"银色";
    }
    return self;
}
- (void) initWithBrand:(NSString*) brand model:(NSString*) model color:(NSString*) clolor
{
    //用 initWithBrand: model: 初始化对象并赋予self,属于复用代码,更方便
    if(self = [self initWithBrand: brand ,model:model])
    {
        //此处只赋值 color 即可
        self.color = colour;
    }
    return self;
}
@end

类的继承

子类继承父类的格式:

@interface SubClass: SuperClass
{
    //定义成员变量
}
//定义方法
@end

子类会继承父类的如下内容:

  • 继承父类的全部成员变量,故而子类中不应该存在与父类同名的成员变量
  • 继承父类的全部方法,包括初始化方法
    接口部分:
#import <Foudation/Foundatioin.h>

@interface MyParent :NSObject
{
    int (nonatomic, assign) _a;
}
@property (nonatomic, assign) int a;
@property int weight;
- (void) showWeight;
@end

@interface MySub: MyParent
- (void) accessOwner;
@end

实现部分:

#import <Foundation/Foundation.h>
#import "MyParent.h"

@plementation MyParent
@snythesize a = _a;
@snythesize weight;
- (id) init
{
    if(self = [super init])
    {
        self->_a = 5;
    }
    return self;
}
- (void) showWeight
{
    NSLog(@"weight is: %d", self.weight);
}
@end

@implementation MySub
{
    //该成员变量会隐藏 MyParent 中的同名成员变量
    int _a;
}
- (id) init    //子类的 init 方法覆盖了父类的 init 方法
{
    if(self = [super init])
    {
        self->_a = 7;
    }
    return self;
}
- (void) accessOwner
{
    //直接访问当前变量的成员
    NSLog(@"当前成员变量的值为:%d", _a);
    //当问父类中被隐藏的成员变量
    NSLog(@"父类中被隐藏的成员变量值为:%d", super.a);
}
@end

main()部分:

#import <Foundation/Foundatioin.h>
#import "MyParent.h"

int main()
{
    @autoreleasepool
    {
        MySub* sub = [[MySub alloc] init];
        [sub accessOwner];  //会依据方法显示子类与父类 a 的值
        sub.weight = 75;    //子类可以访问父类的属性
        [sub showWeight];   //子类可以调用父类的方法
    }
}

多态

多态性

实现部分:

//接口部分忽略,自行编写,MySub为MyBase的子类
#import <Foundation/Foundation.h>
#import "MyBase.h"

@implementation MyBase
- (void) base
{
    NSLog(@"调用MyBase的base方法。");
}
- (void) test
{
    NSLog(@"调用MyBase的test方法。");
}
@end

@implementation MySub
- (void) test
{
    NSLog(@"调用MySub的test方法。");
}
- (void) sub
{
    NSLog(@"调用MySub的sub方法。");
}
@end

main()部分:

#import <Foundation/Foundation.h>
#import "MyBase.h"

int main(int attic, char* argv[])
{
    @autoreleasepool
    {
        //编译时类型与运行时类型不一样,多态发生
        MyBase bc = [[MySub alloc] init];
        //会调用父类的base方法
        [bc base];    
        //对调用子类重写的test方法
        [bc test];    
        //由于 bc 的变异类型为 MyBase ,MyBase 没有提供 sub 方法,所以编译出错
        [bc sub];   
        //将任意类型的指针变量赋值给 id 类型变量
        id dyna = bc;
        [id sub];    //由于 id 类型变量可接受任意类型指针变量,并且id 类型变量可以调用该变量实际所指对象的方法,故而该行代码无错 
    }
}

将子类对象赋予父类指针变量,成为向上转型(upcasting),这种变量可调用的方法范围为父类的方法范围,但实际调用的方法确实子类的方法。

判断指针变量实际类型以及强制类型转换

判断变量实际类型用以下方法:

  • -(BOOL) isKindOfClass:clazz 判断对象是否为clazz或其子类的实例
  • -(BOOL) isSubclassOfClass:clazz 判断对象是否为clazz子类的实例
int main()
{
    @autoreleasepool
    {
        //声明 MySub* sub
        MySub* sub = [[MySub alloc] init];
        //如果 sub 为 MyBase或其子类的实例为 true ,则执行 if 内语句
        if([sub isKindOfClass: [MyBase class]])
        {
            //将 sub 强制转换成 MyBase* 类型并赋予 base
            MyBase* base = (MyBase*) sub;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值