같은 클래스에있는 다른 개체의 개인 필드에 액세스 {

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;
   }
}

디자인은 잊어주세요. 나는 OOP가 개인 객체가 클래스에 개인임을 지정한다는 것을 알고 있습니다. 내 질문은 왜 개인 필드가 개체 수준 액세스가 아닌 클래스 수준 액세스를 갖도록 OOP가 설계 되었습니까?



답변

나는 또한 대답이 조금 궁금합니다.

내가 찾은 가장 만족스러운 답변은 여기 다른 게시물의 Artemix에서 가져온 것입니다 (AClass의 이름을 Person 클래스로 변경하고 있습니다).
왜 객체 수준 대신 클래스 수준 액세스 수정자가 있습니까?

private 한정자는 캡슐화 원칙을 적용합니다.

아이디어는 Person 구현이 시간이 지남에 따라 변경 될 수 있기 때문에 ‘외부 세계’가 Person 내부 프로세스를 변경해서는 안된다는 것입니다 (그리고 구현의 차이를 수정하기 위해 전체 외부 세계를 변경해야합니다-거의 불가능합니다).

Person의 인스턴스가 다른 Person 인스턴스의 내부에 액세스 할 때 두 인스턴스 모두 항상 Person의 구현 세부 정보를 알고 있는지 확인할 수 있습니다. 내부 프로세스의 로직이 변경되면 Person의 코드를 변경하기 만하면됩니다.

편집 : Artemix의 답변에 투표 하십시오 . 복사하여 붙여 넣는 중입니다.


답변

Java 언어 사양, 섹션 6.6.1을 참조하십시오 . 접근성 결정

그것은 말한다

그렇지 않고 멤버 또는 생성자가 선언 된 경우 멤버 또는 생성자의 선언 private을 포함하는 최상위 클래스 (§7.6)의 본문 내에서 발생하는 경우에만 액세스가 허용됩니다.

자세한 내용은 위의 링크를 클릭하십시오. 그래서 대답은 다음과 같습니다. James Gosling과 다른 Java 작성자가 그렇게하기로 결정했기 때문입니다.


답변

좋은 질문. 객체 수준 액세스 수정자는 캡슐화 원칙을 더욱 강화할 것으로 보입니다.

그러나 실제로는 그 반대입니다. 예를 들어 보겠습니다. 해당 개체의 전용 멤버에 액세스 할 수없는 경우 생성자에서 개체를 전체 복사하려고한다고 가정합니다. 그런 다음 가능한 유일한 방법은 모든 개인 구성원에 공용 접근자를 추가하는 것입니다. 이것은 당신의 개체를 만들 것 알몸 시스템의 모든 다른 부분.

따라서 캡슐화는 나머지 세계에 대해 폐쇄되는 것을 의미하지 않습니다. 그것은 당신이 누구에게 열려 있는지 선택하는 것을 의미합니다.


답변

이것은 당신이 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; }
};

아니면 작성하려는 경우 operator+operator-우리의 큰 숫자 클래스.


답변

Java에서 비공개 가시성의 의미가 객체 수준이 아닌 클래스 수준 인 이유에 대한 질문에 대해 2 센트 만하겠습니다.

여기서는 편리함 이 핵심 이라고 생각 합니다 . 사실, 객체 수준의 비공개 가시성은 OP에 의해 설명 된 시나리오에서 다른 클래스 (예 : 동일한 패키지)에 메소드를 노출해야했습니다.

사실 저는 클래스-개인 수준의 가시성 (예 : Java에서 제공)이 객체-개인 수준의 가시성과 비교할 때 문제를 생성한다는 것을 보여주는 예를 만들거나 찾을 수 없었습니다.

즉,보다 세분화 된 가시성 정책 시스템을 사용하는 프로그래밍 언어는 객체 수준과 클래스 수준에서 객체 가시성을 모두 제공 할 수 있습니다.

예를 들어 Eiffel 은 선택적 내보내기를 제공합니다. {NONE} (객체-비공개)에서 {ANY} (공용과 동일하며 기본값)에서 {PERSON}까지 모든 클래스 기능을 원하는 모든 클래스로 내보낼 수 있습니다. (class-private, OP의 예 참조), 특정 클래스 그룹 {PERSON, BANK}.

Eiffel에서 속성을 비공개로 만들고 다른 클래스가 그것에 할당되는 것을 막기 위해 getter를 작성할 필요가 없다는 점에 주목하는 것도 흥미 롭습니다. Eiffel의 공용 속성은 기본적으로 읽기 전용 모드에서 액세스 할 수 있으므로 값을 반환하기 위해 getter가 필요하지 않습니다.

물론 속성을 설정하려면 setter가 필요하지만 해당 속성에 대한 “할당 자”로 정의하여 숨길 수 있습니다. 이를 통해 원하는 경우 setter 호출 대신 더 편리한 할당 연산자를 사용할 수 있습니다.


답변

때문에 private 액세스 한정자는 단지 내에서 그것을 볼 수 렌더링 클래스 . 이 메서드는 여전히 클래스에 있습니다.


답변

private필드는 필드가 선언 된 클래스 / 객체에 액세스 할 수 있습니다. 위치가 아닌 다른 클래스 / 객체에 대해 비공개입니다.