Access Modifiers

1. 주제 분류의 적절성 분석

“Access Modifiers(접근 제어자)” 를 “Computer Science and Engineering > System and Software Architecture > Principles > Programming Paradigms > Object-Oriented Programming(객체지향 프로그래밍)” 에 분류하는 것은 매우 적절합니다. 접근 제어자는 객체지향 프로그래밍 (OOP, Object-Oriented Programming) 의 핵심 원칙인 캡슐화 (encapsulation) 와 정보 은닉 (data hiding) 을 실현하는 주요 수단이기 때문입니다. 클래스, 메서드, 변수 등 구성 요소의 접근 범위를 제어하여 소프트웨어 아키텍처의 구조적 안정성과 보안성을 높이는 데 필수적입니다 [3][5][12].


2. 200 자 요약

접근 제어자 (Access Modifier) 는 클래스, 변수, 메서드 등 객체지향 구성 요소의 접근 범위를 명확히 지정하여 정보 은닉과 캡슐화를 실현한다. 이를 통해 코드의 무결성, 보안성, 유지보수성을 높이고, 의도치 않은 접근이나 변경을 방지한다 [2][3][5][12].


3. 250 자 개요

Access Modifier(접근 제어자) 는 객체지향 프로그래밍에서 클래스, 변수, 메서드, 생성자 등 구성 요소의 접근 권한을 지정하는 키워드다. public, protected, default, private 등 다양한 접근 수준을 제공하며, 이로써 정보 은닉, 캡슐화, 모듈화, 보안성 강화 등 소프트웨어 설계 원칙을 구현한다. 적절한 접근 제어자 사용은 코드의 오용을 방지하고, 유지보수성과 확장성을 높이며, 시스템 아키텍처의 견고함을 보장한다 [3][5][12][17].


I. 핵심 개념

  • 정의: 접근 제어자 (Access Modifier) 는 클래스, 변수, 메서드, 생성자 등 객체지향 구성 요소의 접근 범위를 지정하는 키워드다 [2][3][5][7].
  • 주요 목적: 정보 은닉 (data hiding), 캡슐화 (encapsulation), 코드 무결성 및 보안성 강화, 유지보수성 향상 [3][5][6][9][12].
  • 적용 대상: 클래스, 인터페이스, 필드 (멤버 변수), 메서드, 생성자 등 [5][14][19].
  • 종류:
    • public(공개): 모든 곳에서 접근 가능
    • protected(보호): 같은 패키지 및 상속받은 클래스에서 접근 가능
    • default(기본): 같은 패키지 내에서만 접근 가능 (명시적 키워드 없음)
    • private(비공개): 선언된 클래스 내에서만 접근 가능 [5][6][7][12][13][14][19][20]

II. 주요 내용 정리

1. 배경 및 필요성

  • 객체지향 설계의 핵심 원칙인 정보 은닉과 캡슐화를 실현하기 위해 등장 [3][5][6][9][12].
  • 외부에서 내부 데이터나 구현 세부사항에 직접 접근하는 것을 제한하여, 의도치 않은 데이터 변경이나 오용을 방지 [3][5][6][9][12].
  • 유지보수성, 보안성, 코드의 견고함을 높임 [3][5][12][17].

2. 주요 기능 및 역할

  • 클래스 및 멤버의 접근 범위 지정
  • 정보 은닉 및 캡슐화 실현
  • API 의 명확한 경계 설정
  • 코드 오용 및 버그 방지
  • 상속 및 다형성 지원 [3][5][6][9][12][17]

3. 특징 및 원칙

  • 정보 은닉: 내부 구현을 숨기고, 외부에는 필요한 인터페이스만 노출 [3][5][6][9][12].
  • 캡슐화: 데이터와 메서드를 하나로 묶고, 외부 접근을 제어 [3][5][6][9][12].
  • 최소 권한 원칙: 필요한 최소한의 접근만 허용 (가장 제한적인 접근 제어자 사용 권장)[1][3][5][6][12].
  • 상속과 연계: protected 는 상속 구조에서 자식 클래스 접근을 허용 [5][6][7][12][13][14].

4. 작동 원리 (다이어그램)

flowchart TD
    A[클래스/멤버 선언] --> B{Access Modifier 지정}
    B -->|public| C[어디서든 접근 가능]
    B -->|protected| D[같은 패키지 + 자식 클래스 접근 가능]
    B -->|default| E[같은 패키지 내에서만 접근 가능]
    B -->|private| F[해당 클래스 내에서만 접근 가능]

5. 구조 및 아키텍처

구성 요소

구성 요소기능 및 역할
클래스접근 제어자를 통해 외부 접근 범위 지정
멤버 변수데이터 은닉 및 외부 접근 제한
메서드내부 구현 보호, 외부에 필요한 기능만 노출
생성자객체 생성 방식 제어 (외부에서 생성 제한 등)

필수 구성 요소

  • 접근 제어자 (public, protected, default, private)
  • 클래스, 메서드, 변수 등 선언부

선택 구성 요소

  • getter/setter 메서드 (정보 은닉 시 외부 접근 창구로 제공)
  • 내부 유틸리티 메서드 (보통 private 로 선언)

구조 다이어그램

classDiagram
    class Example {
        -privateField : int
        #protectedField : int
        defaultField : int
        +publicField : int
        +publicMethod()
        -privateMethod()
        #protectedMethod()
        defaultMethod()
    }

6. 구현 기법

구현 기법정의 및 목적예시 (시스템 구성/시나리오)
public어디서든 접근 허용, API 등 외부 공개 목적외부 라이브러리의 공개 메서드
protected상속 구조에서 접근 허용, 내부 확장성 목적프레임워크 내부 확장 포인트
default같은 패키지 내에서만 접근 허용, 모듈화 목적패키지 단위 유틸리티 클래스
private클래스 내부만 허용, 정보 은닉 및 안전성 목적멤버 변수, 내부 헬퍼 메서드
getter/setterprivate 멤버에 대한 안전한 접근 제공private 필드 + public get/set 메서드

7. 장점과 단점

구분항목설명
✅ 장점정보 은닉내부 구현을 숨겨 데이터 무결성 보장
캡슐화외부에 필요한 인터페이스만 노출, 유지보수성 향상
보안성민감 데이터 및 로직 보호, 오용 방지
모듈화명확한 경계 설정으로 코드 재사용성 및 확장성 향상
⚠ 단점남용 시 복잡성 증가지나치게 제한적이면 테스트/유지보수 불편
상속 제한private 멤버는 자식 클래스에서 접근 불가
API 설계 오류잘못된 접근 범위 지정 시 외부 연동 불가

단점 해결 방법

  • 최소 권한 원칙 준수 (가장 제한적인 접근 제어자부터 적용)
  • getter/setter 등 안전한 접근 창구 제공
  • 설계 단계에서 API 경계 명확히 정의

8. 도전 과제 및 해결책

도전 과제설명해결책
적절한 접근 범위 판단미래 확장성, 유지보수성 고려한 적절한 범위 지정코드 리뷰, 자동화 도구 활용, 설계 문서화
남용/오용무분별한 public 사용 등최소 권한 원칙, 코드 표준화
상속 구조 복잡성protected 남용 시 구조 오염설계 단계에서 상속 구조 명확화

9. 분류 기준에 따른 종류 및 유형

접근 제어자클래스 내부같은 패키지상속 (자식)외부 (다른 패키지)
publicOOOO
protectedOOOX
defaultOOXX
privateOXXX

10. 구현 예시 (Python)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class User:
    def __init__(self, name, age):
        self.__name = name         # private
        self._age = age            # protected (관례상)
        self.country = "Korea"     # public

    def get_name(self):            # public getter
        return self.__name

    def set_name(self, name):      # public setter
        self.__name = name

user = User("홍길동", 30)
print(user.country)         # public 접근 가능
print(user.get_name())      # private 접근은 getter로만 가능

11. 실무 적용 예시

적용 분야적용 예시설명
API 설계public 메서드만 공개외부에 필요한 기능만 노출
도메인 모델private 멤버 변수데이터 무결성 및 정보 은닉
프레임워크protected 확장 포인트사용자 정의 확장 지원
모듈화default 패키지 유틸패키지 내부 전용 기능 구현

12. 활용 사례

도메인 모델의 정보 은닉

  • 시스템 구성: 도메인 모델의 멤버 변수를 private, 접근 메서드는 public 으로 설계
  • 다이어그램
classDiagram
    class Account {
        -accountNumber : String
        +getAccountNumber() : String
        +setAccountNumber(num : String)
    }
  • Workflow

    1. 외부에서 Account 객체 생성
    2. setAccountNumber() 로 값 설정 (유효성 검사 포함)
    3. getAccountNumber() 로 값 조회
  • 역할: 정보 은닉, 데이터 무결성 보장, 외부 오용 방지


13. 실무에서 효과적으로 적용하기 위한 고려사항 및 주의할 점

고려사항설명권장사항
최소 권한 원칙가장 제한적인 접근 제어자부터 적용필요 시만 범위 확장
API 경계 명확화외부에 노출할 기능만 public 지정내부 구현은 숨김
코드 리뷰접근 제어자 남용/오용 여부 점검리뷰 체크리스트 활용
문서화접근 범위 및 의도 명확히 기록설계 문서에 명시

14. 최적화하기 위한 고려사항 및 주의할 점

고려사항설명권장사항
유지보수성변경 시 영향 범위 최소화private, protected 적극 활용
성능불필요한 public 멤버 최소화내부 로직은 은닉
확장성상속 구조에서 protected 활용필요시만 공개
테스트 용이성테스트 목적의 접근 범위 조정패키지/모듈 단위 테스트 활용

15. 기타 사항

문제원인영향탐지/진단예방/해결 방법
오용무분별한 public 사용보안 취약, 유지보수 어려움코드 리뷰, 정적 분석 도구최소 권한 원칙, 표준 준수
정보 유출private 미사용민감 데이터 노출보안 점검, 코드 검사캡슐화, getter/setter 활용
상속 구조 혼란protected 남용구조 복잡화설계 리뷰, 문서화상속 최소화, 조합 (composition) 우선

주제와 관련하여 주목할 내용

주제항목설명
정보 은닉캡슐화내부 데이터와 구현을 숨기고 인터페이스만 노출
최소 권한 원칙보안성필요한 최소한의 접근만 허용
상속protected자식 클래스 확장 지원
API 설계public외부와의 명확한 경계 설정
유지보수성private내부 변경 시 외부 영향 최소화

추가로 알아야 할 내용

카테고리간략한 설명주제
SOLID 원칙객체지향 설계 5 대 원칙, 특히 단일 책임/개방폐쇄 원칙과 연계객체지향 설계
캡슐화와 정보 은닉접근 제어자의 근본 원리캡슐화, 정보 은닉
getter/setter 패턴private 멤버 접근을 위한 표준 패턴접근 창구 제공
정적 분석 도구접근 제어자 오용 탐지 자동화코드 품질 관리
UML 클래스 다이어그램접근 제어자 시각화설계 문서화

용어 정리

카테고리용어설명
접근 제어자public모든 곳에서 접근 가능
접근 제어자protected같은 패키지 및 자식 클래스에서 접근 가능
접근 제어자default같은 패키지 내에서만 접근 가능 (키워드 없음)
접근 제어자private선언된 클래스 내에서만 접근 가능
객체지향캡슐화데이터와 메서드를 하나로 묶고 외부 접근을 제한하는 원리
객체지향정보 은닉내부 구현을 숨기고 필요한 정보만 외부에 제공하는 원리
설계 원칙최소 권한 원칙가장 제한적인 권한부터 적용하는 보안 원칙
패턴getter/setterprivate 멤버에 대한 접근을 제공하는 메서드 패턴

참고 및 출처

[1] https://swa.informatik.uni-hamburg.de/files/veroeffentlichungen/ZollerSchmolitzkySCAM2012_01.pdf
[2] https://www.codecademy.com/resources/docs/cpp/access-modifiers
[3] https://www.devx.com/terms/access-modifiers/
[4] https://net-informations.com/faq/oops/access.htm
[5] https://chung-develop.tistory.com/37
[6] https://helloworld-88.tistory.com/41
[7] https://www.tcpschool.com/java/java_modifier_accessModifier
[8] https://studyeasy.org/ko/course-articles/java-articles-ko/s07l22-%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C%EC%9D%98-%EC%A0%91%EA%B7%BC-%EC%A0%9C%ED%95%9C%EC%9E%90-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0/
[9] https://haileysjournal.tistory.com/46
[10] https://velog.io/@khyunjiee/UML-Class-Diagram
[11] https://velog.io/@chldntjr0425/Encapsulation-Access-Modifier
[12] https://studyeasy.org/ko/course-articles/java-articles-ko/s07l23-%EC%83%81%EC%86%8D-%EC%97%86%EC%9D%B4-%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%91%EA%B7%BC-%EC%A0%9C%EC%96%B4%EC%9E%90/
[13] https://velog.io/@yongseok0419/%EC%A0%91%EA%B7%BC%EC%A0%9C%EC%96%B4%EC%9E%90-Access-Modifier
[14] https://kingoflanguages.tistory.com/21
[15] https://johnkdk-dev.tistory.com/32
[16] https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers
[17] https://www.linkedin.com/pulse/understanding-access-modifiers-object-oriented-anusruta-dutta-teksc
[18] https://soundofcoding.tistory.com/131
[19] https://peemangit.tistory.com/394
[20] https://blog.hexabrain.net/119
[21] https://softwareengineering.stackexchange.com/questions/400269/do-access-modifiers-matter
[22] https://velog.io/@dongker/JAVA-%EC%A0%91%EA%B7%BC-%EC%A7%80%EC%A0%95%EC%9E%90-Access-Modifiers-%EC%A0%95%EB%A6%AC
[23] https://chaebob.tistory.com/28
[24] https://bigexecution.tistory.com/297
[25] https://ohj9575.tistory.com/183
[26] https://www.youtube.com/watch?v=9JyWC6Lx6fw
[27] https://ittrue.tistory.com/130
[28] https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/access-modifiers?redirectedfrom=MSDN
[29] https://doohong.github.io/2018/03/05/Java-AccessModifier/
[30] https://dejavuhyo.github.io/posts/java-access-modifiers/
[31] https://min-zero.tistory.com/entry/C-%EA%B8%B0%EB%B3%B8-%EA%B3%B5%EB%B6%80%EC%A0%95%EB%A6%AC-14-OOP-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%A0%91%EA%B7%BC%EC%A0%9C%EC%96%B4%EC%9E%90
[32] https://velog.io/@jaegil123/Access-Level-Modifier
[33] https://wikidocs.net/232
[34] https://velog.io/@thddbs07/UML-Class-Diagram
[35] https://growinghj.tistory.com/3
[36] https://hongong.hanbit.co.kr/%EC%9E%90%EB%B0%94-%EC%A0%91%EA%B7%BC-%EC%A0%9C%ED%95%9C%EC%9E%90%EC%9D%98-%EC%A2%85%EB%A5%98%EC%99%80-%EC%B0%A8%EC%9D%B4public-protected-private/
[37] http://www.ktword.co.kr/test/view/view.php?no=2657
[38] https://you9010.tistory.com/152
[39] https://simplex3510.tistory.com/158

접근 제어자 (Access Modifiers) 는 객체 지향 프로그래밍 (OOP) 의 핵심 개념으로, 클래스의 구성 요소 (필드, 메서드 등) 에 대한 접근 범위를 제어하여 캡슐화 (encapsulation) 를 구현합니다. 이는 소프트웨어 설계의 원칙 중 하나로, 모듈화와 보안성을 높이고 유지보수를 용이하게 합니다.(medium.com)


1. 주제 분류의 적절성 분석

“Access Modifiers” 는 “Computer Science and Engineering > System and Software Architecture > Principles > Programming Paradigms > Object-Oriented Programming” 분류에 적절하게 속합니다. 접근 제어자는 객체 지향 프로그래밍의 캡슐화 원칙을 구현하는 주요 수단으로, 소프트웨어 아키텍처의 설계 원칙과 밀접한 관련이 있습니다.


2. 주제 요약 (200 자 내외)

접근 제어자는 클래스의 멤버에 대한 접근 범위를 정의하여 캡슐화를 구현하는 키워드입니다. 이를 통해 내부 구현을 숨기고, 외부와의 인터페이스를 명확히 하여 모듈화와 보안성을 향상시킵니다.(en.wikipedia.org)


3. 전체 개요 (250 자 내외)

접근 제어자는 객체 지향 프로그래밍에서 클래스의 멤버에 대한 접근 권한을 제어하여 캡슐화를 실현하는 핵심 요소입니다. 이를 통해 내부 구현을 보호하고, 외부와의 명확한 인터페이스를 제공하여 소프트웨어의 모듈화, 보안성, 유지보수성을 향상시킵니다. 각 언어는 다양한 접근 제어자를 제공하며, 이를 적절히 활용하는 것이 중요합니다.


4. 핵심 개념

  • 접근 제어자 (Access Modifiers): 클래스의 멤버 (필드, 메서드 등) 에 대한 접근 범위를 정의하는 키워드입니다.

  • 캡슐화 (Encapsulation): 객체의 내부 상태를 외부로부터 숨기고, 허용된 인터페이스를 통해서만 접근을 허용하는 객체 지향 프로그래밍의 원칙입니다.

  • 정보 은닉 (Information Hiding): 내부 구현 세부사항을 숨기고, 외부에는 필요한 정보만을 제공하여 모듈 간의 결합도를 낮추는 설계 원칙입니다.(stackoverflow.com)


5. 상세 조사 내용

5.1. 배경 및 목적

객체 지향 프로그래밍에서 캡슐화는 객체의 내부 상태를 보호하고, 외부와의 상호작용을 명확히 하여 소프트웨어의 안정성과 유지보수성을 향상시키는 데 목적이 있습니다. 접근 제어자는 이러한 캡슐화를 구현하는 수단으로, 클래스의 멤버에 대한 접근 범위를 제어하여 내부 구현을 보호하고, 외부와의 명확한 인터페이스를 제공합니다.

5.2. 주요 기능 및 역할

  • 보안성 향상: 내부 데이터를 보호하여 외부로부터의 불필요한 접근을 차단합니다.

  • 모듈화: 클래스 간의 명확한 경계를 설정하여 모듈화를 촉진합니다.

  • 유지보수성 향상: 내부 구현 변경 시 외부에 미치는 영향을 최소화하여 유지보수를 용이하게 합니다.

5.3. 특징

  • 언어별 차이: 각 프로그래밍 언어는 접근 제어자를 다르게 구현하며, 사용 방법에도 차이가 있습니다.

  • 접근 범위의 계층 구조: 접근 제어자는 접근 범위에 따라 계층 구조를 형성하여 세밀한 제어가 가능합니다.

5.4. 핵심 원칙

  • 최소 권한 원칙 (Principle of Least Privilege): 필요한 최소한의 권한만을 부여하여 보안을 강화합니다.

  • 정보 은닉: 내부 구현을 숨기고, 외부에는 필요한 정보만을 제공하여 모듈 간의 결합도를 낮춥니다.(linkedin.com)

5.5. 작동 원리

접근 제어자는 컴파일러나 인터프리터에 의해 해석되어, 정의된 접근 범위에 따라 멤버의 접근 가능 여부를 결정합니다. 예를 들어, private 로 선언된 멤버는 해당 클래스 내부에서만 접근이 가능하며, 외부에서는 접근이 제한됩니다.


6. 구현 기법

6.1. 언어별 접근 제어자 비교

언어접근 제어자설명
Javapublic, protected, default, privatedefault 는 동일 패키지 내에서 접근 가능
C#public, protected, internal, private, protected internal, private protectedinternal 은 동일 어셈블리 내에서 접근 가능
Python없음 (관례적으로 _ 또는 __ 사용)언어 차원에서 접근 제어를 강제하지 않음
JavaScriptpublic, private (ES6 이후)# 을 사용하여 private 필드 정의

6.2. 예시 (Python)

1
2
3
4
5
6
7
8
class MyClass:
    def __init__(self):
        self.public_var = 1
        self._protected_var = 2
        self.__private_var = 3

    def get_private_var(self):
        return self.__private_var
  • public_var: 외부에서 자유롭게 접근 가능

  • _protected_var: 관례적으로 보호된 멤버로 취급

  • __private_var: 이름 맹글링 (name mangling) 을 통해 클래스 외부에서 접근 제한 (discuss.codecademy.com, en.wikipedia.org)


7. 장점과 단점

구분항목설명
✅ 장점보안성 향상내부 데이터를 보호하여 외부로부터의 불필요한 접근을 차단
모듈화 촉진클래스 간의 명확한 경계를 설정하여 모듈화를 촉진
유지보수성 향상내부 구현 변경 시 외부에 미치는 영향을 최소화하여 유지보수를 용이하게 함
⚠ 단점복잡성 증가접근 제어자의 과도한 사용은 코드의 복잡성을 증가시킬 수 있음
테스트 어려움private 멤버의 경우 테스트 코드에서 접근이 어려워질 수 있음

단점 해결 방법

  • 복잡성 증가: 접근 제어자의 사용을 최소화하고, 필요한 경우에만 제한을 두어 복잡성을 줄입니다.

  • 테스트 어려움: 테스트를 위해 @VisibleForTesting 과 같은 어노테이션을 사용하거나, 테스트 전용 인터페이스를 제공하여 접근을 허용합니다.(softwareengineering.stackexchange.com)


8. 도전 과제 및 해결책

  • 문제: 접근 제어자의 과도한 사용으로 인한 코드의 복잡성 증가

    • 해결책: 접근 제어자는 필요한 경우에만 사용하고, 기본적으로는 최소한의 제한을 두는 것이 좋습니다.
  • 문제: 테스트 코드에서 private 멤버에 대한 접근 제한


9. 실무 적용 예시

상황적용 예시
API 개발외부에 공개할 메서드는 public 으로 선언하고, 내부 로직은 private 으로 숨김
라이브러리 개발외부에 제공할 인터페이스만 public 으로 노출하고, 구현 세부사항은 private 으로 유지
테스트 코드 작성테스트를 위해 @VisibleForTesting 어노테이션을 사용하여 private 멤버에 접근

10. 실무에서 효과적으로 적용하기 위한 고려사항 및 주의할 점

고려사항설명권장사항
최소 권한 원칙필요한 최소한의 접근 권한만 부여기본적으로 private 사용을 고려
테스트 용이성테스트 코드에서의 접근 필요성 고려테스트 전용 인터페이스 제공
코드 일관성팀 내에서의 접근 제어자 사용 규칙 통일코딩 컨벤션 문서화 및 공유

11. 최적화하기 위한 고려사항 및 주의할 점

고려사항설명권장사항
리팩토링 용이성내부 구현 변경 시 외부에 미치는 영향 최소화접근 제어자를 활용하여 내부 구현 숨김
모듈화클래스 간의 명확한 경

네, “11. 최적화하기 위한 고려사항 및 주의할 점 " 부터 이어서 계속 작성하겠습니다.


11. 최적화하기 위한 고려사항 및 주의할 점 (계속)

고려사항설명권장사항
모듈화클래스 간의 명확한 경계를 설정하고 결합도를 낮춤접근 제어자를 활용해 내부 구현을 숨기고, 인터페이스 기반 설계를 도입
API 안정성외부에 공개된 메서드는 API 계약으로 간주되므로 쉽게 변경하지 않아야 함public API 의 변경을 신중하게 고려하고, @Deprecated 를 통한 단계적 제거
리소스 관리불필요한 인스턴스 접근을 제한하여 메모리와 성능 최적화private 필드 + lazy initialization 기법 활용
보안민감한 정보나 비즈니스 로직이 외부에서 접근되지 않도록 보호privateprotected 사용 + 코드 리뷰를 통한 검증

12. 기타 사항: 발생 가능한 문제와 대응 방안

구분항목설명대응 방안
문제 발생내부 구현 노출외부에서 직접 내부 구현에 접근하면 유지보수성 저하, 보안 위협 발생private 또는 protected 로 제한하고, 외부 인터페이스를 통해 접근하도록 유도
영향의존성 증가내부 필드나 메서드가 외부에 노출되면 강한 결합이 생겨 모듈화 저해내부 요소 은닉과 의존성 주입 (DI, Dependency Injection) 도입
탐지 및 진단테스트 커버리지 부족테스트 시 접근 제한으로 인해 중요한 로직의 검증 누락 가능성테스트 우회 인터페이스 또는 테스트 전용 설정 도입
예방 방법명확한 설계 원칙 부족접근 제어자 사용 기준이 없다면 무분별한 공개로 인한 문제 발생팀 차원의 코딩 컨벤션 수립 및 코드 리뷰 강제
해결 방법리팩토링기존 코드의 접근 제어자를 상황에 맞게 재조정리팩토링 시 자동화 도구와 테스트 기반 접근 권장

13. 주제와 관련하여 주목할 내용

주제항목설명
객체 지향 원칙캡슐화 (Encapsulation)내부 구현을 숨기고 인터페이스만 노출하여 모듈성과 보안성 강화
설계 원칙최소 권한 원칙반드시 필요한 권한만 외부에 제공함으로써 보안 강화
언어별 구현 차이접근 제어자 범위Java, C#, Python, JS 등 언어별로 세분화된 접근 권한 제공 여부 다름
테스팅 전략접근 제한된 멤버 테스트 방법리플렉션 (Reflection), 친구 클래스 (Friend Class), 내부 인터페이스 활용
아키텍처모듈 경계 설정서비스나 모듈 간 강결합을 방지하고 변경 영향 최소화를 위한 경계 설정 필요

14. 추가로 학습해야 할 주제 및 관련 개념

카테고리간략한 설명주제
객체 지향 설계 원칙SOLID 원칙에서 " 단일 책임 “, " 개방 - 폐쇄 “, " 디미터 법칙 " 등과 연관객체 지향 설계, SOLID, OOP
테스트 전략접근 제한 메서드를 효과적으로 테스트하는 기법테스트 우회 기법, 테스트 더블
보안정보 은닉을 통한 시스템 보안성 향상시큐어 코딩, 보안 설계, 보안 리뷰
소프트웨어 아키텍처내부와 외부 인터페이스의 구분, 마이크로서비스 내 접근 제어모듈화, 서비스 계층, API 게이트웨이
언어별 차이점 분석Java, C#, Python, JS 등 접근 제어자 구현 방식 및 철학 차이언어 설계 철학, 런타임 검사, 컴파일러

용어 정리

카테고리용어설명
객체 지향캡슐화 (Encapsulation)객체의 내부 상태를 외부로부터 보호하고 인터페이스를 통해서만 접근 허용
객체 지향정보 은닉 (Information Hiding)내부 구현 세부사항을 감추고 외부에 필요한 정보만 제공하는 설계 기법
보안최소 권한 원칙시스템 구성 요소에게 작업 수행에 필요한 최소 권한만을 부여하는 보안 원칙
테스트테스트 우회 기법접근 제한된 멤버를 테스트하기 위한 인터페이스 또는 리플렉션 등의 기법
아키텍처모듈화시스템을 독립적인 단위로 나누어 설계 및 구현하는 구조적 접근 방식

참고 및 출처


다음 단계로 " 활용 사례 " 와 " 구현 예시 " 로 이어지는 실무 중심 내용을 원하신다면 알려주세요.

좋습니다. 이어서 활용 사례, 구현 예시, 실무 적용 예시 항목부터 차례대로 정리하겠습니다.


15. 활용 사례

사례: Java 기반의 금융 API 플랫폼에서 접근 제어자 활용

설명:
A 금융사는 외부 고객사에 제공하는 Open API 플랫폼을 Java 로 개발하였습니다. 이때 보안상 중요 정보 (계좌 인증, 거래 내역 등) 는 private 으로 캡슐화하고, 외부에 노출되는 API 는 public interface 로만 설계하여 보안성과 유지보수성을 확보했습니다.

시스템 구성도 (Mermaid)

classDiagram
    class AccountService {
        -String accountNumber
        -double balance
        +getBalance()
        +transfer()
    }

    class AccountController {
        +getAccountInfo()
        +doTransfer()
    }

    class ExternalAPI {
        +invokeGetAccountInfo()
    }

    ExternalAPI --> AccountController : 호출
    AccountController --> AccountService : 내부 의존

Workflow

  1. 외부 클라이언트가 ExternalAPI.invokeGetAccountInfo() 호출

  2. AccountControllerAccountService 에 위임

  3. AccountServiceprivate 필드 (accountNumber, balance) 는 외부에서 직접 접근 불가

  4. 반환되는 결과는 public getter 로 캡슐화된 정보만 전달

역할 및 효과

구성 요소역할
private 필드중요한 데이터 은닉 (예: 계좌번호, 잔액 등)
public 메서드허용된 로직만 외부에 노출
controller 계층비즈니스 로직 보호 및 API 와 내부 모듈 연결

16. 구현 예시 (Python 기반)

시나리오: 내부 결제 로직 보호

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class PaymentService:
    def __init__(self):
        self.__api_key = "SECRET123"     # 민감 정보 은닉
        self._transaction_log = []       # 보호된 로그 (외부 접근 제한)

    def process_payment(self, amount):
        if self.__authorize():
            self._transaction_log.append(amount)
            print(f"Paid {amount} successfully.")
        else:
            print("Unauthorized payment attempt.")

    def __authorize(self):
        # 내부 인증 로직 (외부에서 호출 불가)
        return True

설명

  • __api_key: 외부에서 접근 불가능한 민감 정보

  • _transaction_log: 보호된 로그

  • __authorize(): 외부 접근을 제한한 내부 인증 로직

  • 실무에서는 __authorize() 가 외부 API 키와 검증 절차를 포함할 수 있음


17. 실무 적용 예시

사례 번호분야설명
1금융 서비스계좌 정보 및 내부 처리 로직을 private 으로 보호
2IoT 기기 제어장치 상태 변수는 private, 통신 인터페이스는 public 으로 구성
3게임 서버 개발플레이어 상태 (HP, EXP) 는 private, 액션 메서드는 public 처리
4SaaS API 설계엔드포인트는 public, 설정 정보는 private 로 분리
5머신러닝 모델모델 파라미터는 private, 예측 메서드는 public 처리

이어서 제공 가능한 다음 항목

  • 구조 및 아키텍처” 에 대한 상세 분석 및 다이어그램

  • 분류 기준에 따른 종류 및 유형” 정리

  • 도전 과제” 에 대한 기술적 상세 대응

  • 기타 사항” (문제 진단/탐지/예방 및 해결 기법)

필요하신 항목을 알려주시면 바로 이어서 정리해드리겠습니다.

계속해서 아래 항목들을 이어서 작성하겠습니다.


18. 구조 및 아키텍처

필수 구성 요소와 역할

구성 요소역할 및 기능
접근 제어자 (Access Modifier)클래스의 필드, 메서드, 생성자 등 구성 요소에 대한 접근 범위를 지정
클래스 (Class)필드와 메서드의 정의 공간, 접근 제어자의 적용 대상
메서드 (Method)내부 로직 수행, 외부로 공개되는 인터페이스 역할 수행
필드 (Field)객체의 상태 정보 보유, 보통 private 으로 정의하여 외부 접근 제한
인터페이스 (Interface)외부와의 연결 지점, 필요한 최소한의 메서드만 public 으로 노출

선택 구성 요소 (언어 및 환경에 따라 다름)

구성 요소역할 및 기능
패키지/네임스페이스동일 패키지 내에서만 접근 가능하도록 제어 (default, internal 등)
어노테이션/속성접근 제어 보완 또는 테스트 허용 (@VisibleForTesting, friend 등)
reflection/reflex API런타임에 접근 제어 우회 가능, 보안 리스크 동반

구조 및 아키텍처 다이어그램 (Mermaid)

classDiagram
    class User {
        -String name
        -String password
        +getName()
        +authenticate()
    }

    class UserService {
        +login()
        -verifyCredentials()
    }

    class PublicAPI {
        +loginUser()
    }

    PublicAPI --> UserService : public loginUser()
    UserService --> User : private verifyCredentials()

설명

  • User: 민감한 정보를 private 으로 보호하고, 메서드를 통해 간접 노출

  • UserService: 핵심 로직을 private 으로 숨기고 외부에 최소 메서드만 public 처리

  • PublicAPI: 인증된 메서드만 외부에 제공


19. 분류 기준에 따른 종류 및 유형

분류 기준유형설명
접근 수준public어디서든 접근 가능
private해당 클래스 내부에서만 접근 가능
protected해당 클래스 및 자식 클래스에서만 접근 가능
default / internal같은 패키지 (자바)/같은 어셈블리 (C#) 에서 접근 가능
언어별 구분Javapublic, private, protected, (default)
C#public, private, protected, internal, protected internal
Python접근 제어자 없음 (_, __ 관례 사용)
JavaScript (ES2022 이후)public, private, # 키워드 사용
적용 대상클래스, 메서드, 필드, 생성자각각 접근 제어자를 통해 보호 수준을 지정 가능

20. 도전 과제 및 해결책

도전 과제설명해결 방안
과도한 은닉너무 많은 멤버를 private 으로 두면 테스트 및 유지보수가 어려움유연한 설계 적용 + 테스트 우회 인터페이스 활용
접근 제어 우회Reflection 등으로 무단 접근 가능보안 정책 강화, 런타임 검사 추가
팀 내 코드 일관성 부족접근 제어자의 사용 기준이 모호한 경우 발생코딩 컨벤션 정의 및 정적 분석 도구 적용
언어별 접근 제어 정책의 차이언어에 따라 접근 수준이 다르므로 공통 정책 수립이 어려움공통 가이드라인 문서화 및 공통 프레임워크 적용

21. 기타 사항

문제: 잘못된 접근 제어자 사용

항목설명
원인개발자가 기본 접근 제어자 (public) 를 무분별하게 사용할 경우
영향보안 취약, 코드 결합도 증가, 변경 영향도 커짐
탐지정적 코드 분석 도구 (예: SonarQube, PMD 등)
예방코드 리뷰 + 컨벤션 문서화
해결리팩토링을 통해 접근 범위 최소화 (privatepackage-private) 등
기법캡슐화 적용, 인터페이스 분리, 의존성 역전 원칙 (DIP) 적용

용어 정리

카테고리용어설명
객체 지향클래스 (Class)상태 (필드) 와 동작 (메서드) 을 캡슐화한 프로그래밍 단위
접근 제어public / private 등접근 범위를 정의하는 키워드
설계 원칙최소 권한 원칙최소한의 접근만 허용하는 보안 설계 원칙
테스트 전략테스트 우회 인터페이스private 멤버 테스트를 위한 별도 접근 인터페이스
보안 설계Reflection런타임에 접근 권한 우회를 가능하게 하는 기법

참고 및 출처


이상으로 Access Modifiers 주제에 대한 전체 분석을 마쳤습니다.
원하시면 다음으로 이어질 수 있는 관련 주제 (예: SOLID 원칙, 캡슐화 심화, 테스트 전략) 를 제안해드릴 수도 있습니다.

주제인 “Access Modifiers” 에 대해 조사해보겠습니다. 먼저 주제 분류를 검토하고 웹 검색을 통해 최신 정보를 수집하겠습니다.이제 주제 분류에 대한 검토부터 시작하겠습니다.

1. 주제 분류 검토

제시된 분류 “Computer Science and Engineering” > “System and Software Architecture” > “Principles” > “Programming Paradigms” > “Object-Oriented Programming” 는 적절합니다.

근거:

  • **Access Modifiers (접근 제한자)**는 객체지향 프로그래밍의 핵심 원칙인 캡슐화 (Encapsulation) 를 구현하는 주요 메커니즘
  • 클래스, 메서드, 필드의 가시성과 접근성을 제어하는 프로그래밍 언어의 구문적 요소
  • 시스템 설계와 소프트웨어 아키텍처에서 모듈간의 의존성과 결합도를 관리하는 중요한 원칙
  • 객체지향 프로그래밍 패러다임의 데이터 은닉과 정보 은닉을 실현하는 핵심 도구

2. 요약 문장 (200 자 내외)

접근 제한자 (Access Modifiers) 는 객체지향 프로그래밍에서 클래스의 멤버 (필드, 메서드, 생성자) 와 클래스 자체의 가시성과 접근성을 제어하는 키워드로, 캡슐화 원칙을 구현하여 데이터 은닉과 정보 보호를 통해 안전하고 유지보수 가능한 코드 작성을 가능하게 합니다.

3. 전체 개요 (250 자 내외)

접근 제한자는 객체지향 프로그래밍의 핵심 구성 요소로, public, private, protected, internal 등의 키워드를 통해 클래스 멤버의 접근 범위를 정의합니다. 이를 통해 캡슐화를 실현하고, 상속과 다형성을 지원하며, 시스템의 보안성과 안정성을 향상시킵니다. 언어별로 다른 접근 제한자를 제공하며, 적절한 사용을 통해 코드의 유지보수성과 재사용성을 극대화할 수 있습니다.


Access Modifiers (접근 제한자) 완전 분석

제 1 부: 핵심 개념과 이론적 배경

핵심 개념

**접근 제한자 (Access Modifiers)**는 객체지향 프로그래밍에서 클래스, 메서드, 필드, 생성자 등의 접근성과 가시성을 제어하는 키워드입니다. 이들은 캡슐화 (Encapsulation) 원칙을 구현하는 핵심 메커니즘으로, 코드의 구성 요소가 어떤 범위에서 접근 가능한지를 명시적으로 정의합니다.

배경

접근 제한자의 개념은 1960 년대 시뮬라 (Simula) 언어에서 처음 도입되었으며, 1970 년대 스몰토크 (Smalltalk) 를 거쳐 현대의 객체지향 언어들로 발전했습니다. 이는 대규모 소프트웨어 개발에서 모듈간의 의존성을 관리하고 코드의 안정성을 보장하기 위한 필요성에서 출발했습니다.

목적 및 필요성

  1. 캡슐화 구현: 데이터와 메서드를 하나의 단위로 묶고 외부 접근을 제한
  2. 데이터 보호: 민감한 정보의 무단 접근과 수정 방지
  3. 인터페이스 정의: 클래스의 공개 인터페이스와 내부 구현 분리
  4. 유지보수성 향상: 내부 구현 변경이 외부 코드에 미치는 영향 최소화
  5. 코드 안정성: 예상치 못한 데이터 변경과 부작용 방지

주요 기능 및 역할

  • 가시성 제어 (Visibility Control): 클래스 멤버의 접근 범위 정의
  • 접근성 관리 (Accessibility Management): 외부에서의 접근 권한 설정
  • 상속 제어 (Inheritance Control): 하위 클래스에서의 접근 권한 관리
  • 네임스페이스 관리: 패키지나 어셈블리 수준의 접근 제어

특징

  1. 선언적 (Declarative): 키워드를 통한 명시적 접근 제어
  2. 컴파일 타임 검증: 컴파일 시점에 접근 권한 검사
  3. 언어별 차이: 프로그래밍 언어마다 제공하는 접근 제한자 종류 상이
  4. 계층적 구조: 접근 범위의 포함 관계 형성

제 2 부: 핵심 원칙과 작동 원리

핵심 원칙

  1. 최소 권한 원칙 (Principle of Least Privilege): 필요한 최소한의 접근 권한만 부여
  2. 정보 은닉 원칙 (Information Hiding): 내부 구현 세부사항을 외부로부터 숨김
  3. 인터페이스 분리 원칙: 공개 인터페이스와 내부 구현의 명확한 분리
  4. 단일 책임 원칙: 각 접근 수준별로 명확한 책임 범위 정의

주요 원리

graph TD
    A[Access Modifiers] --> B[Encapsulation]
    A --> C[Information Hiding]
    A --> D[Interface Definition]
    
    B --> E[Data Protection]
    B --> F[Method Control]
    
    C --> G[Implementation Details]
    C --> H[Internal State]
    
    D --> I[Public Interface]
    D --> J[Contract Definition]
    
    E --> K[Unauthorized Access Prevention]
    F --> L[Behavior Control]
    G --> M[Change Isolation]
    H --> N[State Integrity]
    I --> O[Client Interaction]
    J --> P[API Specification]

작동 원리

sequenceDiagram
    participant Client
    participant Compiler
    participant Class
    participant Member
    
    Client->>Compiler: Access Request
    Compiler->>Class: Check Access Modifier
    Class->>Member: Verify Permission
    
    alt Access Allowed
        Member->>Class: Grant Access
        Class->>Compiler: Permission Granted
        Compiler->>Client: Access Successful
    else Access Denied
        Member->>Class: Deny Access
        Class->>Compiler: Permission Denied
        Compiler->>Client: Compilation Error
    end

제 3 부: 구조 및 아키텍처

구성 요소

필수 구성요소:

  1. 접근 키워드 (Access Keywords)

    • 기능: 접근 수준을 명시하는 언어별 키워드
    • 역할: 컴파일러에게 접근 제어 규칙 전달
    • 특징: 언어별로 다른 키워드 세트 제공
  2. 스코프 정의 (Scope Definition)

    • 기능: 접근 가능한 범위의 경계 설정
    • 역할: 클래스, 패키지, 어셈블리 등의 접근 범위 관리
    • 특징: 계층적 구조로 조직화
  3. 컴파일러 검증 시스템 (Compiler Verification)

    • 기능: 컴파일 시점에 접근 권한 검사
    • 역할: 부적절한 접근 시도 차단
    • 특징: 정적 분석을 통한 실시간 검증

선택 구성요소:

  1. 어노테이션 기반 접근 제어

    • 기능: 메타데이터를 통한 세밀한 접근 제어
    • 역할: 런타임 접근 제어와 리플렉션 지원
    • 특징: 프레임워크와의 통합 지원
  2. 패키지/네임스페이스 레벨 제어

    • 기능: 모듈 단위의 접근 제어
    • 역할: 대규모 시스템의 모듈간 의존성 관리
    • 특징: 배포 단위별 접근 제어

구조 다이어그램

graph TB
    subgraph "Access Modifier Architecture"
        A[Language Keywords] --> B[Compiler Parser]
        B --> C[Access Control Engine]
        C --> D[Scope Manager]
        D --> E[Permission Validator]
        
        subgraph "Access Levels"
            F[Public]
            G[Private]
            H[Protected]
            I[Internal/Package]
            J[Protected Internal]
            K[Private Protected]
        end
        
        subgraph "Target Elements"
            L[Classes]
            M[Methods]
            N[Fields]
            O[Constructors]
            P[Properties]
        end
        
        E --> F
        E --> G
        E --> H
        E --> I
        E --> J
        E --> K
        
        C --> L
        C --> M
        C --> N
        C --> O
        C --> P
    end

제 4 부: 구현 기법과 실무 적용

구현 기법

1. 기본 접근 제한자 구현

정의: 언어에서 제공하는 표준 접근 제한자를 사용한 기본적인 접근 제어 구성: public, private, protected 등의 키워드 활용 목적: 클래스의 기본적인 캡슐화 구현

실제 예시 (Java):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class BankAccount {
    private double balance;           // private: 클래스 내부에서만 접근
    protected String accountType;     // protected: 상속 클래스에서 접근 가능
    public String accountNumber;      // public: 모든 곳에서 접근 가능
    
    public void deposit(double amount) {  // public 메서드
        if (amount > 0) {
            this.balance += amount;
        }
    }
    
    private void validateTransaction() {  // private 메서드
        // 내부 검증 로직
    }
}
2. 게터/세터 패턴 (Getter/Setter Pattern)

정의: private 필드에 대한 제어된 접근을 제공하는 public 메서드 구성: private 필드 + public getter/setter 메서드 목적: 데이터 무결성 보장과 검증 로직 추가

실제 예시 (Python):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Temperature:
    def __init__(self):
        self._celsius = 0  # protected 필드 (convention)
    
    @property
    def celsius(self):     # getter 메서드
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):  # setter 메서드
        if value < -273.15:
            raise ValueError("Temperature cannot be below absolute zero")
        self._celsius = value
    
    @property
    def fahrenheit(self):  # 계산된 속성
        return (self._celsius * 9/5) + 32
3. 인터페이스 기반 접근 제어

정의: 인터페이스를 통한 공개 계약 정의와 구현 은닉 구성: 인터페이스 정의 + 구현 클래스의 private 멤버 목적: 구현과 인터페이스의 완전한 분리

실제 예시 (C#):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public interface IPaymentProcessor
{
    bool ProcessPayment(decimal amount);
    string GetTransactionId();
}

public class CreditCardProcessor : IPaymentProcessor
{
    private string _cardNumber;        // private 구현 세부사항
    private string _securityCode;      // private 보안 정보
    private readonly ILogger _logger;  // private 의존성
    
    public bool ProcessPayment(decimal amount)  // public 인터페이스 구현
    {
        if (!ValidateCard())  // private 메서드 호출
            return false;
            
        return ProcessTransaction(amount);  // private 구현
    }
    
    public string GetTransactionId()  // public 인터페이스 구현
    {
        return GenerateTransactionId();  // private 구현
    }
    
    private bool ValidateCard() { /* 내부 구현 */ }
    private bool ProcessTransaction(decimal amount) { /* 내부 구현 */ }
    private string GenerateTransactionId() { /* 내부 구현 */ }
}

장점과 단점

구분항목설명
✅ 장점캡슐화 구현데이터와 메서드를 논리적으로 묶어 관리
데이터 보호무단 접근과 부적절한 수정으로부터 데이터 보호
유지보수성 향상내부 구현 변경이 외부에 미치는 영향 최소화
인터페이스 명확화공개 API 와 내부 구현의 명확한 분리
코드 안정성컴파일 타임 검증을 통한 오류 조기 발견
⚠ 단점코드 복잡성 증가접근 제어로 인한 코드 구조 복잡화
개발 속도 저하초기 설계 단계에서의 추가 고려사항
리플렉션 제약동적 접근 시 제한사항 발생
언어별 차이플랫폼 간 이식성 문제 가능성

단점 해결 방법:

  • 코드 복잡성: 명확한 설계 원칙과 문서화를 통한 복잡성 관리
  • 개발 속도: IDE 지원과 코드 생성 도구 활용
  • 리플렉션 제약: 적절한 public API 제공과 어노테이션 활용
  • 언어별 차이: 공통 패턴과 추상화 계층 사용

도전 과제

  1. 적절한 접근 수준 결정

    • 설명: 각 멤버에 대한 최적의 접근 제한자 선택의 어려움
    • 해결책: 최소 권한 원칙 적용과 점진적 개방 전략
  2. 상속 계층에서의 접근 제어

    • 설명: 복잡한 상속 구조에서 접근 권한 관리의 복잡성
    • 해결책: 명확한 상속 정책과 인터페이스 활용
  3. 테스트 가능성 확보

    • 설명: private 멤버의 단위 테스트 어려움
    • 해결책: 패키지 레벨 접근자와 테스트 전용 인터페이스 활용
  4. 성능 최적화

    • 설명: 접근자 메서드로 인한 성능 오버헤드
    • 해결책: 컴파일러 최적화와 인라인 메서드 활용

분류 기준에 따른 종류 및 유형

분류 기준종류설명지원 언어
접근 범위Public모든 곳에서 접근 가능Java, C#, C++, Python
Private선언된 클래스 내에서만 접근Java, C#, C++, Python
Protected같은 클래스와 하위 클래스에서 접근Java, C#, C++, Python
모듈 수준Internal같은 어셈블리/패키지 내에서 접근C#, Java (package)
Package같은 패키지 내에서 접근 (기본값)Java
File같은 파일 내에서만 접근C# (file)
복합 타입Protected InternalProtected 또는 Internal 조건 만족C#
Private ProtectedProtected 와 Internal 조건 모두 만족C#

구현 예시

다음은 도서관 관리 시스템의 Book 클래스를 통한 접근 제한자 활용 예시입니다:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
class Book:
    # 클래스 변수 (공개)
    library_name = "Central Library"
    
    def __init__(self, isbn, title, author):
        # 공개 속성
        self.isbn = isbn
        
        # 보호된 속성 (상속 클래스에서 접근 가능)
        self._title = title
        self._author = author
        
        # 비공개 속성 (클래스 내부에서만 접근)
        self.__borrower = None
        self.__borrow_date = None
        self.__is_available = True
    
    # 공개 메서드 - 외부에서 사용할 수 있는 인터페이스
    def get_info(self):
        """도서 기본 정보 반환"""
        return f"{self._title} by {self._author} (ISBN: {self.isbn})"
    
    def is_available(self):
        """도서 대출 가능 여부 확인"""
        return self.__is_available
    
    def borrow(self, borrower_name):
        """도서 대출 처리"""
        if self.__is_available:
            self.__borrower = borrower_name
            self.__borrow_date = self._get_current_date()
            self.__is_available = False
            return True
        return False
    
    def return_book(self):
        """도서 반납 처리"""
        if not self.__is_available:
            self.__borrower = None
            self.__borrow_date = None
            self.__is_available = True
            return True
        return False
    
    # 보호된 메서드 - 하위 클래스에서 재정의 가능
    def _get_current_date(self):
        """현재 날짜 반환 (하위 클래스에서 재정의 가능)"""
        from datetime import datetime
        return datetime.now().strftime("%Y-%m-%d")
    
    # 비공개 메서드 - 내부 구현 세부사항
    def __validate_isbn(self, isbn):
        """ISBN 유효성 검증 (내부 사용 전용)"""
        return len(isbn) == 13 and isbn.isdigit()
    
    # 프로퍼티를 통한 제어된 접근
    @property
    def title(self):
        return self._title
    
    @property
    def author(self):
        return self._author
    
    @property
    def borrower_info(self):
        """대출자 정보 (읽기 전용)"""
        if not self.__is_available:
            return f"Borrowed by {self.__borrower} on {self.__borrow_date}"
        return "Available"

# 사용 예시
book = Book("9781234567890", "Design Patterns", "Gang of Four")

# 공개 인터페이스 사용
print(book.get_info())  # 정상 작동
print(book.is_available())  # 정상 작동
book.borrow("John Doe")  # 정상 작동

# 프로퍼티를 통한 안전한 접근
print(book.title)  # 정상 작동
print(book.borrower_info)  # 정상 작동

# 보호된 멤버 접근 (권장하지 않음)
print(book._title)  # 작동하지만 권장하지 않음

# 비공개 멤버 직접 접근 시도 (실패)
# print(book.__borrower)  # AttributeError 발생

이 예시에서는:

  • Public: get_info(), is_available(), borrow() 등 외부에서 사용할 메서드
  • Protected: _title, _author, _get_current_date() 등 상속 시 접근 가능한 멤버
  • Private: __borrower, __is_available, __validate_isbn() 등 내부 구현 세부사항

실무 적용 예시

분야적용 사례접근 제한자 활용효과
웹 개발RESTful API 컨트롤러public 메서드로 엔드포인트 노출, private 로 비즈니스 로직 은닉API 안정성과 보안 강화
게임 개발캐릭터 상태 관리private 필드로 HP/MP 보호, public 메서드로 액션 제공게임 밸런스와 치팅 방지
금융 시스템계좌 관리 클래스private 잔액 필드, public 거래 메서드금융 데이터 보안과 무결성
IoT 디바이스센서 데이터 처리protected 센서 접근, public 데이터 읽기하드웨어 보호와 확장성
데이터베이스ORM 엔티티 클래스private 식별자, public 속성 접근자데이터 일관성과 검증

활용 사례: 전자상거래 결제 시스템

시나리오: 온라인 쇼핑몰의 결제 처리 시스템에서 접근 제한자를 활용한 보안 강화

시스템 구성:

graph TB
    subgraph "Payment Processing System"
        A[PaymentController] --> B[PaymentService]
        B --> C[CreditCardProcessor]
        B --> D[PayPalProcessor]
        B --> E[BankTransferProcessor]
        
        C --> F[EncryptionService]
        C --> G[BankAPIClient]
        
        F --> H[SecurityVault]
        G --> I[External Bank API]
    end
    
    subgraph "Access Control Layers"
        J[Public Interface] --> K[Protected Methods]
        K --> L[Private Implementation]
    end

시스템 구성도:

classDiagram
    class PaymentController {
        +processPayment(amount, method)
        +getPaymentStatus(transactionId)
        -validateRequest(request)
        -logTransaction(transaction)
    }
    
    class PaymentService {
        +executePayment(paymentData)
        #validatePaymentData(data)
        -selectProcessor(method)
        -executeTransaction(processor, data)
    }
    
    class CreditCardProcessor {
        +processPayment(cardData, amount)
        #validateCard(cardNumber)
        -encryptCardData(data)
        -callBankAPI(encryptedData)
        -generateTransactionId()
    }
    
    class SecurityVault {
        -cardNumbers: Map
        -encryptionKeys: Map
        +encryptData(data)
        +decryptData(encryptedData)
        -rotateKeys()
    }
    
    PaymentController --> PaymentService
    PaymentService --> CreditCardProcessor
    CreditCardProcessor --> SecurityVault

활용 사례 Workflow:

sequenceDiagram
    participant Client
    participant Controller
    participant Service
    participant Processor
    participant Vault
    
    Client->>Controller: POST /payment (public)
    Controller->>Controller: validateRequest() (private)
    Controller->>Service: executePayment() (public)
    Service->>Service: validatePaymentData() (protected)
    Service->>Service: selectProcessor() (private)
    Service->>Processor: processPayment() (public)
    Processor->>Processor: validateCard() (protected)
    Processor->>Processor: encryptCardData() (private)
    Processor->>Vault: encryptData() (public)
    Vault->>Vault: rotateKeys() (private)
    Vault-->>Processor: encrypted data
    Processor->>Processor: callBankAPI() (private)
    Processor-->>Service: transaction result
    Service-->>Controller: payment result
    Controller-->>Client: HTTP response

각 계층의 역할:

  • PaymentController (공개 계층): 클라이언트 요청 접수와 응답 처리
  • PaymentService (서비스 계층): 비즈니스 로직과 프로세서 선택
  • CreditCardProcessor (구현 계층): 신용카드 결제 세부 구현
  • SecurityVault (보안 계층): 민감한 데이터 암호화와 키 관리

이 사례에서 접근 제한자는:

  • Public: 외부 API 와 서비스간 인터페이스
  • Protected: 상속을 통한 확장 가능한 검증 로직
  • Private: 보안이 중요한 암호화와 내부 구현 세부사항

실무에서 효과적으로 적용하기 위한 고려사항 및 주의할 점

구분고려사항설명권장사항
설계 단계최소 권한 원칙필요한 최소한의 접근 권한만 부여처음에는 제한적으로 설계 후 필요시 확장
인터페이스 우선 설계공개 API 를 먼저 정의하고 구현클라이언트 관점에서 필요한 기능 정의
상속 구조 고려하위 클래스의 접근 필요성 검토protected 사용 시 신중한 설계 필요
구현 단계일관성 유지프로젝트 전체에서 일관된 접근 제어 패턴코딩 컨벤션과 가이드라인 수립
문서화접근 제한 이유와 사용법 명시각 public 메서드의 용도와 제약사항 문서화
테스트 고려테스트 가능한 구조 설계패키지 레벨 접근자나 테스트 전용 메서드 제공
유지보수점진적 개방필요시에만 접근 수준 완화하위 호환성을 유지하면서 신중한 변경
리팩토링 영향접근 제한자
유지보수리팩토링 영향접근 제한자 변경이 클라이언트 코드에 미치는 영향 분석변경 전 영향도 분석과 단계적 마이그레이션

최적화하기 위한 고려사항 및 주의할 점

구분고려사항설명권장사항
성능 최적화인라인 최적화컴파일러의 메서드 인라인 활용단순한 getter/setter 는 인라인 후보로 설계
접근자 오버헤드메서드 호출 비용 vs 캡슐화 이익성능 크리티컬한 부분은 프로파일링 후 결정
메모리 사용량불필요한 래퍼 객체 생성 방지값 타입과 참조 타입의 적절한 선택
확장성플러그인 아키텍처동적 모듈 로딩과 접근 제어인터페이스 기반 설계와 의존성 주입
다국어 지원언어별 접근 제어 차이 고려공통 패턴 사용과 추상화 계층 구성
마이크로서비스서비스간 경계와 접근 제어API Gateway 와 서비스 메시 활용
보안 강화리플렉션 보안런타임 접근 제어 우회 방지보안 매니저와 권한 검증 로직 추가
직렬화 보안객체 직렬화 시 민감 데이터 보호transient 키워드와 커스텀 직렬화 구현
코드 난독화컴파일된 코드의 리버스 엔지니어링 방지상용 난독화 도구와 코드 보호 기법 적용

기타 사항

접근 제한자 관련 주요 문제들

1. 접근 권한 충돌 문제

원인:

  • 다중 상속이나 인터페이스 구현 시 접근 권한 불일치
  • 오버라이딩 시 접근 수준 변경으로 인한 충돌

영향:

  • 컴파일 에러 발생
  • 예상치 못한 런타임 동작
  • 코드 유지보수 어려움

탐지 및 진단:

1
2
3
4
5
6
7
8
// 문제 예시 - 접근 수준 축소 시도
class Parent {
    protected void method() { }
}

class Child extends Parent {
    private void method() { }  // 컴파일 에러: 접근 수준 축소 불가
}

예방 방법:

  • 상속 설계 시 접근 제한자 정책 수립
  • 인터페이스 설계 시 일관된 접근 수준 적용
  • 코드 리뷰에서 접근 권한 변경 검토

해결 방법 및 기법:

  • 추상 클래스나 인터페이스를 통한 접근 수준 통일
  • 컴포지션 패턴으로 상속 대체
  • 어댑터 패턴을 통한 접근 수준 조정
2. 순환 의존성과 접근 제어

원인:

  • 패키지 간 순환 참조와 접근 제한자 조합
  • Friend 클래스 패턴의 부적절한 사용

영향:

  • 모듈 간 결합도 증가
  • 테스트 어려움
  • 리팩토링 복잡성 증가

탐지 및 진단:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 문제 예시 - 순환 의존성
# file: module_a.py
from module_b import ClassB

class ClassA:
    def __init__(self):
        self._partner = ClassB()
        
# file: module_b.py  
from module_a import ClassA  # 순환 의존성

class ClassB:
    def __init__(self):
        self._partner = ClassA()

예방 방법:

  • 의존성 그래프 분석 도구 사용
  • 레이어드 아키텍처 적용
  • 인터페이스를 통한 의존성 역전

해결 방법 및 기법:

  • 의존성 주입 컨테이너 사용
  • 이벤트 기반 아키텍처 도입
  • 공통 인터페이스 모듈 분리
3. 테스트 접근성 문제

원인:

  • Private 메서드의 단위 테스트 어려움
  • 모킹 (Mocking) 이 어려운 구조
  • 테스트 데이터 설정의 복잡성

영향:

  • 테스트 커버리지 감소
  • 버그 발견 지연
  • 리팩토링 위험성 증가

탐지 및 진단:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public class Calculator
{
    private decimal CalculateTax(decimal amount)  // 테스트하기 어려운 private 메서드
    {
        // 복잡한 세금 계산 로직
        return amount * GetTaxRate();
    }
    
    private decimal GetTaxRate()  // 외부 의존성이 있는 private 메서드
    {
        // 외부 API 호출
    }
    
    public decimal CalculateTotal(decimal amount)
    {
        return amount + CalculateTax(amount);
    }
}

예방 방법:

  • 테스트 가능한 설계 원칙 적용
  • 의존성 주입을 통한 격리
  • 패키지 레벨 접근자 활용

해결 방법 및 기법:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 해결 예시 - 의존성 주입과 인터페이스 분리
public interface ITaxCalculator
{
    decimal CalculateTax(decimal amount);
}

public class Calculator
{
    private readonly ITaxCalculator _taxCalculator;
    
    public Calculator(ITaxCalculator taxCalculator)
    {
        _taxCalculator = taxCalculator;
    }
    
    public decimal CalculateTotal(decimal amount)
    {
        return amount + _taxCalculator.CalculateTax(amount);
    }
}

// 테스트에서 Mock 객체 사용 가능
4. 성능 저하 문제

원인:

  • 과도한 접근자 메서드 사용
  • 불필요한 메서드 호출 오버헤드
  • 가상 메서드 디스패치 비용

영향:

  • 애플리케이션 성능 저하
  • 메모리 사용량 증가
  • 응답 시간 지연

탐지 및 진단:

  • 프로파일링 도구를 통한 핫스팟 분석
  • 메서드 호출 빈도 측정
  • 메모리 할당 패턴 분석

예방 방법:

  • 성능 크리티컬 경로 식별
  • 인라인 후보 메서드 설계
  • 값 타입 활용 고려

해결 방법 및 기법:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 성능 최적화 예시
public class Point {
    public final double x, y;  // final public 필드로 직접 접근
    
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
    
    // getter 없이 직접 필드 접근으로 성능 향상
}

// 또는 레코드 클래스 사용 (Java 14+)
public record Point(double x, double y) {}
5. 플랫폼 호환성 문제

원인:

  • 언어별 접근 제한자 차이
  • 런타임 환경의 제약사항
  • 라이브러리 간 호환성 문제

영향:

  • 크로스 플랫폼 개발 어려움
  • 라이브러리 통합 문제
  • 코드 이식성 저하

탐지 및 진단:

  • 다중 플랫폼 빌드 테스트
  • 호환성 매트릭스 구성
  • 자동화된 호환성 검증

예방 방법:

  • 표준 패턴과 관례 사용
  • 플랫폼별 어댑터 계층 구성
  • 공통 인터페이스 정의

해결 방법 및 기법:

  • 추상화 계층을 통한 플랫폼 차이 흡수
  • 팩토리 패턴으로 플랫폼별 구현 분리
  • 조건부 컴파일과 특성 기반 설계

용어 정리

카테고리용어설명
기본 개념캡슐화 (Encapsulation)데이터와 메서드를 하나의 단위로 묶고 외부 접근을 제한하는 OOP 원칙
가시성 (Visibility)프로그램의 다른 부분에서 특정 요소를 볼 수 있는 정도
접근성 (Accessibility)프로그램의 다른 부분에서 특정 요소에 접근할 수 있는 권한
접근 수준Public모든 곳에서 접근 가능한 최고 수준의 가시성
Private선언된 클래스 내에서만 접근 가능한 최소 수준의 가시성
Protected같은 클래스와 하위 클래스에서 접근 가능한 중간 수준의 가시성
Internal같은 어셈블리나 패키지 내에서만 접근 가능한 모듈 수준 가시성
설계 원칙정보 은닉 (Information Hiding)객체의 내부 구현 세부사항을 외부로부터 숨기는 설계 원칙
최소 권한 원칙 (Principle of Least Privilege)필요한 최소한의 접근 권한만 부여하는 보안 원칙
인터페이스 분리 (Interface Segregation)공개 인터페이스와 내부 구현을 명확히 분리하는 설계 원칙
구현 기법게터/세터 (Getter/Setter)Private 필드에 대한 제어된 접근을 제공하는 Public 메서드
프로퍼티 (Property)필드처럼 사용되지만 실제로는 메서드인 언어 기능
어노테이션 (Annotation)메타데이터를 통해 추가적인 접근 제어 정보를 제공하는 기능
기술 용어리플렉션 (Reflection)런타임에 객체의 메타데이터를 검사하고 조작하는 기능
직렬화 (Serialization)객체를 데이터 스트림으로 변환하는 과정
인라인 최적화 (Inline Optimization)컴파일러가 메서드 호출을 해당 메서드의 본문으로 대체하는 최적화

참고 및 출처

주제와 관련하여 주목할 내용

주제항목설명
새로운 기술Record 클래스Java 14+ 에서 도입된 불변 데이터 클래스, 자동 접근자 생성
Init-only 프로퍼티C# 9 에서 도입된 초기화 전용 프로퍼티
File-scoped 접근 제한자C# 11 에서 도입된 파일 범위 접근 제한
보안 강화모듈 시스템Java 9 의 Project Jigsaw, 모듈 수준 접근 제어
Strong Name.NET 의 어셈블리 보안과 접근 제어
코드 액세스 보안런타임 권한 기반 접근 제어 시스템
성능 최적화Value Types구조체와 값 타입을 통한 성능 향상
Span.NET 의 메모리 효율적 접근 제어
인라인 어셈블리C++ 의 저수준 최적화 기법
아키텍처 패턴CQRS명령과 조회의 분리를 통한 접근 제어
헥사고날 아키텍처포트와 어댑터를 통한 계층별 접근 제어
마이크로서비스서비스 경계와 API 게이트웨이 기반 접근 제어

추가로 알아야 하거나 학습해야할 내용들

카테고리간략한 설명주제
고급 OOP 개념접근 제한자와 연관된 심화 객체지향 개념들Multiple Inheritance, Mixins, Traits, Abstract Classes vs Interfaces
디자인 패턴접근 제어를 활용한 설계 패턴들Factory Pattern, Builder Pattern, Proxy Pattern, Facade Pattern
메타프로그래밍런타임 접근 제어와 동적 기능들Reflection, Annotations, Decorators, Aspect-Oriented Programming
함수형 프로그래밍함수형 언어의 접근 제어 메커니즘Immutability, Pure Functions, Module Systems, Type Systems
언어별 고급 기능각 언어의 독특한 접근 제어 기능들Python Descriptors, C++ Friend Classes, Scala Sealed Classes
보안 아키텍처시스템 수준의 접근 제어 설계OAuth, JWT, Role-Based Access Control, Principle of Least Privilege
컴파일러 이론접근 제어의 구현 원리Symbol Tables, Scope Resolution, Type Checking, Code Generation
테스팅 전략접근 제어가 있는 코드의 테스트 방법론Unit Testing Private Methods, Mocking, Test Doubles, Integration Testing

객체지향 프로그래밍 (OOP) 에서 접근 제어자 (Access Modifiers) 는 클래스, 메서드, 변수 등의 접근 범위를 제어하는 중요한 개념이다. 이를 통해 캡슐화를 구현하고 코드의 안정성과 유지보수성을 향상시킬 수 있다.

접근 제어자를 적절히 사용하면 객체지향 프로그래밍의 핵심 원칙인 캡슐화를 효과적으로 구현할 수 있으며, 이는 코드의 품질과 유지보수성을 크게 향상시킨다.

접근 제어자의 종류

  1. public

    • 가장 넓은 접근 범위를 가진다.
    • 어떤 클래스에서든 접근이 가능하다.
    • 모든 패키지의 모든 클래스에서 이 요소에 접근할 수 있다.
    1
    2
    3
    4
    5
    6
    
    class BankAccount:
        def __init__(self):
            self.account_number = "123-456-789"  # public 변수
    
        def get_balance(self):  # public 메서드
            return self.balance
    
  2. protected

    • 같은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근 가능하다.
    • 동일 패키지 혹은 다른 패키지에 있는 자식 클래스에서만 접근할 수 있다.
    • Java 에서는 protected 키워드를 사용하고, Python 에서는 변수명 앞에 _ 를 붙여 표현한다.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    class BankAccount:
        def __init__(self):
            self._transaction_limit = 1000000  # protected 변수
    
        def _verify_transaction(self, amount):  # protected 메서드
            return amount <= self._transaction_limit
    
    class SavingsAccount(BankAccount):
        def withdraw(self, amount):
            if self._verify_transaction(amount):  # 상속받은 클래스에서 protected 멤버 접근
                # 출금 처리
                pass
    
  3. default (package-private)

    • 접근 제어자를 명시하지 않았을 때 자동으로 적용된다.
    • 같은 패키지 내에서만 접근 가능하다.
  4. private

    • 가장 좁은 접근 범위를 가진다.
    • 같은 클래스 내에서만 접근 가능하다.
    • 외부에서 접근이 불가능하며, 선언된 클래스 내에서만 접근이 가능하다.
    • Java 에서는 private 키워드를 사용하고, Python 에서는 변수명 앞에 __ 를 붙여 표현한다.
    1
    2
    3
    4
    5
    6
    
    class BankAccount:
        def __init__(self):
            self.__balance = 0  # private 변수
    
        def __calculate_interest(self):  # private 메서드
            return self.__balance * 0.05
    

각 접근 제어자의 접근 범위를 표로 정리하면 다음과 같다:

접근 제어자동일 클래스동일 패키지자식 클래스전체
publicOOOO
protectedOOOX
defaultOOXX
privateOXXX

접근 제어자의 적용 범위

접근 제어자는 다음과 같은 요소에 적용될 수 있다:

  • 클래스 (class)
  • 인터페이스 (Interface)
  • 멤버 변수
  • 멤버 메서드

접근 제어자의 중요성

  1. 캡슐화 구현

    • 객체의 내부 구현을 외부로부터 숨기고, 객체의 상태를 보호한다.
  2. 코드의 안정성 향상

    • 불필요한 접근을 제한함으로써 코드의 안정성을 높인다.
  3. 유지보수성 개선

    • 코드의 구조를 명확히 하여 유지보수를 용이하게 한다.
  4. 재사용성 증대

    • 적절한 접근 제어를 통해 코드의 재사용성을 높일 수 있다.

접근 제어자 사용 예시

Python: 명시적인 접근 제어자를 제공하지 않지만, 네이밍 컨벤션을 통해 유사한 기능을 구현한다.

  • 관례적인 접근 제어 시스템
  • 실제로는 모든 멤버가 public
  • 네임 맹글링을 통한 private 구현
  • 개발자의 규약 준수에 의존
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class BankAccount:
    def __init__(self, holder, initial_balance):
        # public: 어디서든 접근 가능 (명시적인 키워드 없음)
        self.account_holder = holder
        
        # protected: 관례적으로 한 개의 언더스코어로 표시 
        # (실제로는 접근 가능하나 내부 사용을 권장)
        self._account_type = "Savings"
        
        # private: 이름 맹글링을 통해 실제 접근을 어렵게 함
        self.__balance = initial_balance
        
    def get_balance(self):
        # private 멤버에 접근하는 public 메서드
        return self.__balance
    
    def _protected_method(self):
        # protected 메서드
        return "내부 사용 권장"
    
    def __private_method(self):
        # private 메서드
        return "클래스 내부에서만 사용"

# 상속 클래스
class SavingsAccount(BankAccount):
    def print_info(self):
        print(self.account_holder)     # public 접근 가능
        print(self._account_type)      # protected 접근 가능
        # print(self.__balance)        # private 직접 접근 불가능

Javascript:  # 접두사를 사용하여 private 필드를 구현할 수 있다.

  • 최근 private 필드 문법 (#) 도입
  • protected 는 관례적으로만 존재
  • 클래스 필드와 메서드에 대한 private 지원
  • 모듈 시스템을 통한 캡슐화 지원
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// ES2022부터 지원되는 private 필드 문법 사용
class BankAccount {
    // private 필드 선언 (# 사용)
    #balance;
    #calculateInterest;
    
    // public 필드
    accountHolder;
    
    // protected는 JavaScript에서 직접적으로 지원하지 않음
    _accountType;  // 관례적으로 사용하나 실제 보호되지 않음

    constructor(holder, initialBalance) {
        this.accountHolder = holder;      // public
        this._accountType = "Savings";    // 관례적 protected
        this.#balance = initialBalance;   // private
        
        // private 메서드 정의
        this.#calculateInterest = () => {
            return this.#balance * 0.05;
        };
    }

    // public 메서드
    getBalance() {
        return this.#balance;
    }

    // private 필드를 사용하는 public 메서드
    addInterest() {
        const interest = this.#calculateInterest();
        this.#balance += interest;
        return this.#balance;
    }
}

// 사용 예시
const account = new BankAccount("김철수", 1000000);
console.log(account.accountHolder);     // public 접근 가능
console.log(account._accountType);      // 접근 가능하나 권장되지 않음
// console.log(account.#balance);       // private 접근 불가능 (SyntaxError)

Java: 명시적인 접근 제어자를 제공한다.

  • 가장 엄격하고 명확한 접근 제어 시스템 제공
  • 4 가지 수준의 접근 제어자 (public, protected, default, private)
  • 컴파일 시점에서 접근 제어 검사
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// BankAccount.java
public class BankAccount {
    // public: 어디서든 접근 가능
    public String accountHolder;
    
    // protected: 같은 패키지 내 클래스와 상속받은 클래스에서 접근 가능
    protected String accountType;
    
    // default(package-private): 같은 패키지 내에서만 접근 가능
    String branchCode;
    
    // private: 같은 클래스 내에서만 접근 가능
    private double balance;

    public BankAccount(String holder, double initialBalance) {
        this.accountHolder = holder;
        this.balance = initialBalance;
        this.accountType = "Savings";
        this.branchCode = "BR001";
    }

    // private 멤버에 접근하기 위한 public 메서드
    public double getBalance() {
        return this.balance;
    }
}

// SavingsAccount.java
public class SavingsAccount extends BankAccount {
    public void printAccountInfo() {
        System.out.println(this.accountHolder);    // public 접근 가능
        System.out.println(this.accountType);      // protected 접근 가능
        System.out.println(this.branchCode);       // default 접근 가능
        // System.out.println(this.balance);       // private 접근 불가능
    }
}

주의사항

  1. 하나의 대상에 여러 개의 제어자를 조합해서 사용할 수 있지만, 접근 제어자는 하나만 사용해야 한다.
  2. 클래스의 접근 제어자로는 public 과 default 만 사용할 수 있다.
  3. 메서드 오버라이딩 시, 상위 클래스의 메서드보다 더 좁은 접근 제어자를 사용할 수 없다.

용어 정리

용어설명

참고 및 출처