Obj C:不能从子类中的父类继承公共属性

时间:2014-09-16 17:35:16

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

我在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 = race;

使用未声明的标识符_age你的意思是年龄?谁能告诉我哪里出错了?谢谢。

3 个答案:

答案 0 :(得分:3)

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

您可以在子类

的界面中合成ivar
@synthesize age = _age;

或者您可以在超类的接口上声明受保护的ivar,以便在子类上可见。

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

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

答案 1 :(得分:1)

由于clang编译器现在可以自动合成属性,因此在大多数情况下,您无需合成属性。

  

Objective-C属性的自动合成

     

Clang为声明属性的自动合成提供支持。运用   这个功能,clang提供了那些属性的默认合成   声明@dynamic并没有用户提供的支持getter和   二传手术方法。 __has_feature(objc_default_synthesize_properties)   在clang版本中检查此功能的可用性   使用

但在某些情况下(某些例子在此question中),您应该明确地将它们合成。

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

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

你的代码,你会没事的。

答案 2 :(得分:0)

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

设置它
self.age = age;