已经向这个有趣的线程添加了很多答案,但是,我还没有找到导致这种行为发生的真正原因。让我试试看:
时光倒流
在80年代的Smalltalk和90年代中期的Java之间的某个地方,面向对象的概念已经成熟。Smalltalk引入了信息隐藏,最初不是将其视为仅面向对象的概念(1978年首次提及),因为类的所有数据(字段)都是私有的,所有方法都是公共的。在90年代OO的许多新发展中,Bertrand Meyer尝试在他的里程碑式的《面向对象的软件构造(OOSC)》一书中将许多OO概念正式化,从那以后,它被视为(几乎)关于OO概念和语言设计的权威性参考。 。
在私密性的情况下
根据迈耶(Meyer)的观点,应为定义的一组类提供一种方法(第192-193页)。显然,这提供了非常高的信息隐藏粒度,classA和classB及其所有后代可以使用以下功能:
feature {classA, classB}
methodName
对于private
他来说,是这样说的:如果不明确声明类型对其自己的类可见,则无法在限定的调用中访问该功能(方法/字段)。即,如果x
是变量,x.doSomething()
则不允许。当然,在类本身内部也允许不合格的访问。
换句话说:要允许同一类的实例进行访问,必须显式允许该类的方法访问。有时称为实例专用与类专用。
编程语言中的实例专用
我知道目前至少有两种语言使用实例私有信息隐藏而不是类私有信息隐藏。一种是由Meyer设计的语言Eiffel,它将OO发挥到了极致。另一个是Ruby,它是当今更为通用的语言。在Ruby中,private
表示:“专用于此实例”。
语言设计的选择
已经提出,对于编译器来说,很难允许实例私有。我不这么认为,因为只允许或不允许对方法的合格调用相对简单。如果允许使用私有方法,doSomething()
并且不允许使用私有方法,则x.doSomething()
语言设计者可以有效地定义私有方法和字段的仅实例可访问性。
从技术角度来看,没有理由选择任何一种方式(尤其是考虑到Eiffel.NET可以使用IL做到这一点,即使具有多重继承,也没有内在的理由不提供此功能)。
当然,这是一个问题,正如其他人已经提到的那样,如果没有私有方法和字段的类级别可见性的特征,很多方法可能会更难编写。
为什么C#仅允许类封装而不允许实例封装
如果您查看实例封装上的Internet线程(该术语有时用于表示一种事实,即语言在实例级别(而不是类级别)上定义了访问修饰符),那么通常就不会理解该概念。但是,考虑到某些现代语言(至少对于私有访问修饰符)使用实例封装,使您认为它可以并且在现代编程世界中有用。
但是,诚然,C#的语言设计在C ++和Java方面最为艰苦。尽管Eiffel和Modula-3也在其中,但考虑到Eiffel缺少的许多功能(多重继承),我认为在私有访问修饰符方面,他们选择了与Java和C ++相同的路由。
如果您真的想知道为什么您应该尝试获得Eric Lippert,Krzysztof Cwalina,Anders Hejlsberg或从事C#标准工作的任何人。不幸的是,我在带注释的C#编程语言中找不到确定的注释。