2016-11-17 66 views
2

我想继承我的几个派生类将使用的基类属性和方法。我希望这些属性和方法得到完全保护,以便它们只能在派生类中显示,而不能在任何外部类中显示。但它总是给我一些错误。目标中的属性继承C

@interface BasePerson : NSObject 
@end 

@interface BasePerson() 

@property (nonatomic, strong) NSMutableArray<Person*>* savedPersons; 
@property (nonatomic) BOOL shouldSavePerson; 

@end 



@interface DerivedPerson1 : BasePerson 

@end 

@implementation DerivedPerson1 

- (instancetype)init 
{ 
    if (self = [super init]) { 
     self.savedPersons = [NSMutableArray array]; 
     self.shouldSavePerson = NO; 
    } 

    return self; 
} 

它总是给我

Property 'savedPersons' not found on object of type 'DerivedPerson1 *' 
Property 'shouldSavePerson' not found on object of type 'DerivedPerson1 *' 

我怎样才能让目标C使用继承的,我不想savedPersons和shouldSavePerson属性是外部类可见的错误。我只希望它们在我的基类和所有派生类中可见。

任何帮助将是伟大的。谢谢

+0

你能否让我知道派生类的父类名称。 它是UIViewController还是NSObject? –

+0

它的NSObject。这有什么区别吗? – Madu

+0

你的代码看起来不错,不会在编译时大喊错误 – Tj3n

回答

0

Objective-C没有成员访问控制的方法,但你可以使用头文件来模拟它。

BasePerson.h

@interface BasePerson : NSObject 

    @property (strong,nonatomic) SomeClass *somePublicProperty; 

    -(void) somePublicMethod; 
@end 

BasePerson-Private.h

#import "BasePerson.h" 

@interface BasePerson() 

@property (nonatomic, strong) NSMutableArray<Person*>* savedPersons; 
@property (nonatomic) BOOL shouldSavePerson; 

@end 

BasePerson.m

#import "BasePerson-Private.h" 

... 

DerivedPerson1.h

#import "BasePerson-Private.h" 

@inteface DerivedPerson1 : BasePerson 

... 

@end 

现在任何#imports BasePerson.h类将只能看到公共方法。正如我所说的,这只是模拟访问控制,因为如果一个类#imports * BasePerson-Private.h“他们将看到私有成员;这只是如何C/Objective-C。”

0

我们可以实现使用@protected访问符

@interface BasePerson : NSObject { 
    @protected NSMutableArray *savedPersons; 
    @protected BOOL shouldSavePerson; 
    } 

DerivedPerson1.m


@implementation DerivedPerson1 

- (instancetype)init 
{ 
    if (self = [super init]) { 
     self->savedPersons = [NSMutableArray array]; 
     self->shouldSavePerson = NO; 
    } 

    return self; 
} 

@end 

OtherClass.m


#import "OtherClass.h" 
    #import "BasePerson.h" 

    @implementation OtherClass 

    - (void)awakeFromNib { 
     BasePerson *base = [[BasePerson alloc]init]; 
     base->savedPersons = @[];//Getting Error. Because it is not a subclass. 
    } 

    @end 
0

这不是ObjectiveC真正支持的东西。虽然有一些方法。所以让我们看看。

如果你把一个属性放在源文件类扩展中,那么它不会被公开,你也不能在子类中访问它。

一种方法是将所有子类放入与基类相同的源文件中。这并不是一个好的解决方案,因为您确实想为单独的类提供单独的文件。

在​​源文件中导入BaseClass.m似乎是合乎逻辑的,但这会产生链接器错误,说明您有重复的符号。

并将溶液:延伸到一个单独的标题

独立。所以,你有一个MyClass

页眉:

#import <Foundation/Foundation.h> 

@interface MyClass : NSObject 

@end 

来源:

#import "MyClass.h" 
#import "MyClassProtected.h" 

@implementation MyClass 

- (void)foo { 
    self.someProperty = @"Some text from base class"; 
} 

@end 

然后再创建一个头文件(只有标题)MyClassProtected.h它具有如下:

#import "MyClass.h" 

@interface MyClass() 

@property (nonatomic, strong) NSString *someProperty; 

@end 

和子类MyClassSubclass

页眉:

#import "MyClass.h" 

@interface MyClassSubclass : MyClass 

@end 

和源:

#import "MyClassSubclass.h" 
#import "MyClassProtected.h" 

@implementation MyClassSubclass 

- (void)foo { 
    self.someProperty = @"We can set it here as well"; 
} 

@end 

所以,现在如果用户MyClassSubclass他不会有访问受保护的财产基本上是你想要的。但缺点是用户可能仍然会导入MyClassProtected.h,之后他将有权访问该房产。