斯坦福IOS7教程:私有属性和方法也会被子类继承怎么理解

kyrr 发布于 2014年01月10日
无人欣赏。

All methods (including properties) are inherited by subclasses regardless of whether they are public or private.

意思是私有方法和属性会被继承,但是子类看不见?

共5条回复
tinyfool 回复于 2014年01月12日

当然……,这就是继承啊

morpheus1984 回复于 2014年01月12日

1楼 @tinyfool 楼主可能是想问,这种继承怎么用呢?子类又不可见

玉楼 回复于 2014年01月12日

2楼 @morpheus1984 如果你完全不可见就说明不希望你用,可能这些方法和属性是纯私有的,也可能直接开放它们是不安全的。如果你在继承中希望使用父类中的私有方法和属性,要么是父类设计时没有考虑到你的应用场景;要么就是你的设计和用法有问题。

coredump 回复于 2014年01月12日

private这种modifier只是一种弱约束,runtime下和一般property/method没有任何不同:

object_getInstanceVariable(the_object, "_ivar_name", &the_private_ivar);

这就是Objective-C不需要C++那样引入friend关键字的原因,说到C++ friend关键字还有个经典笑话: You can't touch my private, but my friends can. 对Objective-C来说就成了: I said you can't touch my private, but if you did touch, I can only say: やめて

董一凡 回复于 2014年01月13日

这个功能是非常有用的,举个例子

@interface IamBase ()
- (void)privatePrint;
@end

@implementation IamBase

- (void)privatePrint {
    NSLog(@"I am Base");
}

- (void)printName {
    [self privatePrint];
}

@end

@interface IamDerived ()
-(void)privatePrint;

@end

@implementation IamDerived

-(void)privatePrint {
    NSLog(@"I am Derived");
}

@end

这时候你做如下调用

IamBase * base = [[IamDerived alloc]init];
[base printName];

会打印出 I am Derived

在设计的时候,printName是对外描述的接口,而privatePrint是对派生类的实现需求。不过在object-c里,这个功能并不是经常用的,相反在c++里,这是一个非常有用的设计手法,我可以把privatePrint设为纯虚函数,也就意味着,所有使用IamBase的人只知道对外接口printName,而privatePrint是意味着实现合约,所有的派生类必须实现这个函数。对外接口和对派生类的实现合约被分离出来了。职责单一化是有很大的意义的

C++里这个有专门的名字叫做NVI(non-virtual interface)惯用法

登录 或者 注册