访问同一class级另一个对象的私人领域

class Person { private BankAccount account; Person(BankAccount account) { this.account = account; } public Person someMethod(Person person) { //Why accessing private field is possible? BankAccount a = person.account; } } 

请忘记devise。 我知道OOP指定私有对象对于类是私有的。 我的问题是,为什么面向对象的devise使得私有领域具有类级别的访问权限而不是对象级别的访问权限

我对答案也有点好奇。

我find的最满意的答案是来自Artemix的另一篇文章(我正在用Person类重命名AClass): 为什么要使用类级访问修饰符而不是对象级?

私有修饰符强制封装原则。

这个想法是“外部世界”不应该改变Person的内部过程,因为Person的实现可能会随着时间的推移而改变(并且你将不得不改变整个外部世界来修复实现中的差异 – 这几乎是不可能的)。

当Person的实例访问其他Person实例的内部时,可以确定两个实例总是知道Person的实现细节。 如果人员进程内部的逻辑被改变了 – 你所要做的就是改变Person的代码。

编辑:请upvote Artemix的答案。 我只是复制粘贴而已。

请参阅Java语言规范,第6.6.1节。 确定可访问性

它指出

否则,如果成员或构造函数被声明为private ,则只有当它出现在包含成员或构造函数的声明的顶级类(§7.6)的主体内时,才允许访问。

点击上面的链接了解更多详情。 所以答案是:因为James Gosling和Java的其他作者决定这样做。

好问题。 看来,对象级访问修改器会更加强化封装原则。

但实际上这是相反的。 我们来举个例子。 假设你想在构造函数中深度拷贝一个对象,如果你不能访问该对象的私有成员。 那么唯一可能的方法是向所有私人成员添加一些公共访问者。 这将使您的对象裸体系统的所有其他部分。

所以封装并不意味着封闭世界其他地方。 这意味着select你想要开放的人。

因为private 修饰符只会在类中呈现它。 这种方法仍然在课堂上

private字段可以在声明该字段的类/对象中访问。 对于位于其之外的其他类/对象是私有的。

这是有效的,因为你在class Person – 一个类允许在它自己types的类中戳。 当你想写一个拷贝构造函数时,这真的很有帮助,例如:

 class A { private: int x; int y; public: A(int a, int b) x(a), y(b) {} A(A a) { x = ax; y = yx; } }; 

或者,如果我们想写operator+operator-为我们的大数字类。

你是否试图说任何对象都不能通过任何可能的方式访问这个私有属性? 有这个属性有什么意义? 在某种程度上,这个属性是对物体状态的贡献,但是这个状态对其他物体是不知道的。

在Java中使用reflection概念是可能的修改字段和方法私有

Java的改变

首先我们必须明白的是,我们所要做的就是必须遵循oops原则,所以封装就是将数据封装在包(即类)中,而不是将所有数据表示为对象并且易于访问。 所以如果我们把这个领域看作非私有领域,那么它就是非个人化的。 并导致了不好的实践。

就我的2美分的问题,为什么Java的私有可见性的语义是类级而不是对象级。

我想说便利似乎是这里的关键。 事实上,在OP所示的场景中,对象级别的私有可见性将迫使将方法暴露给其他类(例如,在相同的包中)。

事实上,我既不能够进行调制,也不能find一个例子,说明在私营层面(比如由Java提供的)的可见性,如果与对象私有层面的可见性相比,会产生任何问题。

也就是说,具有更加细化的可见性策略系统的编程语言可以在对象级别和类级别提供对象可见性。

例如Eiffel提供了select性导出:您可以将{NONE}(object-private)到{ANY}(相当于public,也是默认值)的任何classfunction导出到{PERSON} (class级 – 私人,参见OP的例子),到特定的class级{PERSON,BANK}。

有趣的是,在Eiffel中,你不需要将属性设为private,并写一个getter来防止其他类被分配给它。 Eiffel中的公共属性在默认情况下是以只读模式访问的,所以你不需要getter就可以返回它们的值。

当然,你仍然需要一个setter来设置一个属性,但是你可以通过定义该属性的“assigner”来隐藏它。 这允许你,如果你愿意,使用更方便的赋值运算符而不是setter调用。

Java中的private是您写入的类级访问。 斯卡拉也反对私人写作private[this]和其他各种方式在这里详细http://alvinalexander.com/scala/how-to-control-scala-method-scope-object-private-package

在Java中最有可能的私有类级访问被认为是足够的,并与C ++在那个时候同步。

我认为这在java中是足够的,因为一个类被写入一个文件,所以作者可以决定如果真的想要访问不同实例之间的成员。 在斯卡拉你可以inheritance多种特性的行为,这可能会改变游戏。