【问题标题】:Obj C: Can't inherit public property from parent class in child classObj C:不能从子类中的父类继承公共属性
【发布时间】:2014-09-16 17:35:15
【问题描述】:

我在 Objective-C 中练习继承,这是我的 Person 父类

// This is Person.h
@interface Person : NSObject

@property(nonatomic, strong) NSNumber *age;
@property(nonatomic, strong) NSString *race;

-(instancetype)init;
-(instancetype)initWithAge:(NSNumber*)age andRace:(NSString*)race;

@end

这就是我在学生课上尝试做的事情

// This is Student.h
#import "Person.h"

@interface Student : Person

@property(nonatomic, strong) NSString *classification;
@property(nonatomic, strong) NSString *major;

@end

// This is Student.m
#import "Student.h"
#import "Person.h"

@implementation Student

-(instancetype)init
{   
    return [self initWithClassification:@"Freshman" andMajor:@"Computer Science"
                                 andAge:[[NSNumber alloc] initWithInt:20] andRace:@"Caucasian"];
}

-(instancetype)initWithClassification:(NSString*)classification andMajor:(NSString*)major
                               andAge:(NSNumber*)age andRace:(NSString*)race
{
    self = [super init];

if (self)
{
    _classification = classification;
    _major = major;
    _age = age;
    _race = race;
}

return self;
}

@end

编译器不喜欢我的做法 _age = 年龄; _race = 种族;

使用未声明的标识符_age 你是指年龄吗?有人能告诉我哪里出错了吗?谢谢。

【问题讨论】:

  • 子类应该避免初始化继承的实例变量。这应该留给超类初始化代码,这就是为什么你的初始化方法应该总是调用[super init...]

标签: ios objective-c oop inheritance parent-child


【解决方案1】:

当你声明一个这样的属性时,clang 会自动为你@synthesize它(即它会创建一个 getter 和 setter),但是合成的属性对子类不可见,你有不同的选择让它工作。

可以在子类的接口中合成ivar

@synthesize age = _age;

或者你可以在超类的接口上声明受保护的ivar,这样子类上就可以看到。

@interface Person : NSObject {
    @protected NSNumber *_age;
}

或者你可以在你的子类上使用self.age = ...,根本不用ivar。

【讨论】:

    【解决方案2】:

    由于 clang 编译器现在可以自动综合您没有的属性,在大多数情况下,可以综合您的属性。

    Objective-C 属性的自动综合

    Clang 支持声明属性的自动合成。使用 这个特性,clang 提供了这些属性的默认合成,而不是 声明 @dynamic 并且没有用户提供支持 getter 和 设置方法。 __has_feature(objc_default_synthesize_properties) 在 clang 的版本中检查此功能的可用性 用过。

    但在某些情况下(一些例子在这个question)你应该明确地综合它们。

    在这种情况下,要解决您的问题,您只需添加:

    @synthesize age = _age;
    @synthesize race = _race;
    

    你的代码,你会没事的。

    【讨论】:

      【解决方案3】:

      子类可以访问属性,但不能访问支持变量。所以你应该设置它

      self.age = age;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-03
        • 2013-04-11
        • 2018-07-03
        • 1970-01-01
        • 1970-01-01
        • 2020-11-08
        相关资源
        最近更新 更多