Objective -c入门-继承(8)

目录

一、创建一个新类,命名为BNREmployee,并将其设置为BNRPerson的子类

二、覆盖方法

三、supper

三、继承层次

五、description方法和%@转换说明

在创建BNRPerson类的时候,将其声明为了NSObject子类,这意味着BNRPerson实例除了会拥有在BNRPerson中定义的实例变量和方法外,还会拥有在NSObject中定义的实例变量和方法。对此,可以称BNRPerson继承了NSObject的实例变量和方法。

一、创建一个新类,命名为BNREmployee,并将其设置为BNRPerson的子类

 在BNREmployee.h文件中增加三个属性,员工的ID、雇佣日期和办公室紧急码。同时声明一个方法,基于员工的雇佣日期来计算员工的工龄。

#import "BNRPerson.h"

NS_ASSUME_NONNULL_BEGIN

@interface BNREmployee : BNRPerson

@property (nonatomic) unsigned int employeeID;
@property (nonatomic) unsigned int officeAlarmCode;
@property (nonatomic) NSDate* hireDate;
- (double) yearOfEmployment;

@end

NS_ASSUME_NONNULL_END

BNREmploy.m实现代码如下:

#import "BNREmployee.h"

@implementation BNREmployee
- (double) yearOfEmployment
{
    //判断是否有一个非nil的hireDate
    if(self.hireDate) {
        NSDate* now = [NSDate date];
        //NSTimeInterval是double类型
        NSTimeInterval secs = [now timeIntervalSinceDate:self.hireDate];
        //根据秒数计算年数
        return secs / 31557600.0;  //除以每年的秒数
    } else {
        return 0;
    }
}
@end

打开main.m文件,导入BNREmployee.h,创建BNREmplyee的实例对象

#import <Foundation/Foundation.h>
#import "BNREmployee.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //创建一个BNREmployee的实例
        BNRPerson* mikey = [[BNREmployee alloc] init];
        //使用存方法给实例变量赋值
        mikey.heightInMeters = 1.62;
        mikey.weightInKilos = 46;
        
        //使用取方法打印实例变量的值
        float height = mikey.heightInMeters;
        int weight = mikey.weightInKilos;
        NSLog(@"mikey is %.2f meters tall and weights %d kilos", height, weight);
        
        //使用定制的方法打印相应的BMI的值
        float bmi = [mikey bodyMassIndex];
        NSLog(@"mikey has a BMI of %.2f", bmi);
    }
    return 0;
}

⚠️main.m中没有导入BNRPerson.h文件。对编译器来说BNREmployee.h包含了#import "#import "BNREmployee.h"这个语句,所以不必再导入一遍。

下面对main.m文件做一些更新,给mikey设置employeeID,然后设置雇佣日期。 

#import <Foundation/Foundation.h>
#import "BNREmployee.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //创建一个BNREmployee的实例
        BNREmployee* mikey = [[BNREmployee alloc] init];
        //使用存方法给实例变量赋值
        mikey.heightInMeters = 1.62;
        mikey.weightInKilos = 46;
        mikey.employeeID = 12;
        mikey.hireDate = [NSDate dateWithNaturalLanguageString:@"Aug 2nd, 2010"];
        
        //使用取方法打印实例变量的值
        float height = mikey.heightInMeters;
        int weight = mikey.weightInKilos;
        NSLog(@"mikey is %.2f meters tall and weights %d kilos", height, weight);
        NSLog(@"Employee %u hired on %@", mikey.employeeID, mikey.hireDate);
        
        //使用定制的方法打印相应的BMI的值和员工工龄
        float bmi = [mikey bodyMassIndex];
        double years = [mikey yearsOfEmployment];
        NSLog(@"BMI of %.2f, has worked with us for %.2f years.", bmi, years);
    }
    return 0;
}

⚠️:这里做了改变BNREmployee* mikey = [[BNREmployee alloc] init];

二、覆盖方法

通常子类要与父类有所不同。

假设,员工的BMI都是19。在这种情况下,可以覆盖BNREmployee的bodyMassIndex方法。

#import "BNREmployee.h"

@implementation BNREmployee
- (double) yearsOfEmployment
{
    //判断是否有一个非nil的hireDate
    if(self.hireDate) {
        NSDate* now = [NSDate date];
        //NSTimeInterval是double类型
        NSTimeInterval secs = [now timeIntervalSinceDate:self.hireDate];
        //根据秒数计算年数
        return secs / 31557600.0;  //除以每年的秒数
    } else {
        return 0;
    }
}
//覆盖了父类的方法
-(float) bodyMassIndex
{
    return 19.0;
}
@end

覆盖方法只能改变方法的实现,无法概拜年它的声明方式,方法的名称、返回值类型及参数的类型都必须保持相同。

三、supper

覆盖一个方法的时候,子类可以利用父类的实现,而不是整个替换。

假设员工的BMI的值,是在BNRPerson方法的结果基础上乘上0.9并返回新的值,就可以使用super指令。

//覆盖了父类的方法
-(float) bodyMassIndex
{
    float normalBMI = [super bodyMassIndex];
    return normalBMI * 0.9;
}

三、继承层次

 NSObject虽然有很多的方法,但是只有一个实例变量:isa指针。任何一个对象的isa指针都会指向创建该对象的类。

例如:创建了一个BNRPerson实例,那么isa就是BNRPerson,如果创建了一个NSString实例,那么isa就是NSString。

给对象发送消息的时候,对象就会查询是否有该消息名的方法。

如果没有就继续查询它的父类,以此类推。直到继承链的顶端为止。

如果找不到,程序就会报错。

但是如果使用了super,就等于告诉对象“运行指定的方法,但是从对象的父类开始查找”。

五、description方法和%@转换说明

在调用NSLog()的时候,我们使用了%@让对象描述自己。

处理%@时,程序会向相应的指针变量所致的对象发送description消息。

description方法灰返回一个描述类实例的字符串。

下面我们在BNREmployee.m文件中,覆盖description方法。

#import "BNREmployee.h"

@implementation BNREmployee
……
- (NSString*) description
{
    return [NSString stringWithFormat:@"<Emplyee %d>", self.employeeID];
}
@end

在main.m中进行使用。

//NSLog(@"%@ hired on %@", mikey, mikey.hireDate);

#import <Foundation/Foundation.h>
#import "BNREmployee.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //创建一个BNREmployee的实例
        BNREmployee* mikey = [[BNREmployee alloc] init];
        //使用存方法给实例变量赋值
        mikey.heightInMeters = 1.62;
        mikey.weightInKilos = 46;
        mikey.employeeID = 12;
        mikey.hireDate = [NSDate dateWithNaturalLanguageString:@"Aug 2nd, 2010"];
        
        //使用取方法打印实例变量的值
        float height = mikey.heightInMeters;
        int weight = mikey.weightInKilos;
        NSLog(@"mikey is %.2f meters tall and weights %d kilos", height, weight);
        NSLog(@"%@ hired on %@", mikey, mikey.hireDate);
        
        //使用定制的方法打印相应的BMI的值和员工工龄
        float bmi = [mikey bodyMassIndex];
        double years = [mikey yearsOfEmployment];
        NSLog(@"BMI of %.2f, has worked with us for %.2f years.", bmi, years);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值