访问同一类中另一个对象的私有字段

Nag*_*ran 76 .net c++ java oop

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;
   }
}
Run Code Online (Sandbox Code Playgroud)

请忘记设计.我知道OOP指定私有对象是该类的私有对象.我的问题是,为什么OOP设计为私有字段具有类级访问而不是对象级访问

Iwa*_*ria 53

我对答案也有点好奇.

我找到的最令人满意的答案来自Artemix的另一篇文章(我用Person类重命名了AClass): 为什么有类级访问修饰符而不是对象级?

private修饰符强制执行Encapsulation原则.

这个想法是"外部世界"不应该对Person内部流程进行更改,因为Person实现可能会随着时间的推移而发生变化(并且您必须更改整个外部世界以修复实现中的差异 - 这几乎是不可能的).

当Person的实例访问其他Person实例的内部时 - 您可以确保两个实例始终知道Person的实现细节.如果Person流程内部的逻辑发生了变化 - 您所要做的就是更改Person的代码.

编辑:请upvote Artemix的答案.我只是复制粘贴它.

  • @NicolasBarbulesco我认为答案中给出的理由是合理的.比如说你想在Java类中实现`equals(Object)`方法来检查`Person`对象与另一个`Person`实例的相等性.您可能希望让外部世界检查这两个实例是否相等,但您可能不希望使用公共访问器方法公开检查与外界的相等性所需的所有类的私有字段.对"private"字段进行类级访问可以实现这样的方法,而不需要实现这样的公共方法. (16认同)
  • 这可能是原因.但这不是一个坏主意**.这鼓励了不良做法.访问"Person"类中的`Person`字段的开发人员不必知道整个类的实现.好的做法是使用访问器,而不必知道访问器的操作. (4认同)

jlo*_*rdo 17

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

它指出

否则,如果声明了成员或构造函数private,那么当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问.

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

  • +1用于引用JLS和该结论 (3认同)

Wei*_*Qiu 10

好问题.似乎对象级访问修饰符将进一步强制执行封装原则.

但实际上它是另一种方式.我们来举个例子吧.假设您要在构造函数中深层复制对象,如果您无法访问该对象的私有成员.然后唯一可能的方法是向所有私有成员添加一些公共访问者.这将使您的对象裸露到系统的所有其他部分.

所以封装并不意味着对世界其他所有国家都是封闭的.这意味着选择你想要对谁开放.

  • 但是让一个对象负责提供自身的副本不是更好吗?然后,如果您需要一个对象的深层副本,无论您是同一类的另一个对象还是不同类的对象都没有关系:它是相同的机制,“o.deepCopy()”或其他。 (4认同)
  • 这个答案需要投票!其他答案只是重新陈述了“规则”,但只有这个答案真正揭示了规则背后的原因并切中要害。 (2认同)

Mat*_*son 6

这是有效的,因为您处于class Person- 一个类可以在它自己的类类型中进行查看。当您想要编写复制构造函数时,这确实很有帮助,例如:

class A
{
   private:
      int x;
      int y;
   public:
      A(int a, int b) x(a), y(b) {}
      A(A a) { x = a.x; y = y.x; }
};
Run Code Online (Sandbox Code Playgroud)

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