개발을 시작하시는 여러분, 정보가 너무 많고 배워야 할 것도 산더미라 어디서부터 시작해야 할지 막막하신가요? 내일배움캠프 수료생들이 4개월 동안 배운 엄선된 핵심 개념을 직접 정리해서 알려 드립니다. 공부하다 막히거나 헷갈리는 개념이 있다면 개념 콕으로 정리해보세요.
접근 제한자(접근 제어자, Access Modifiers)란?
접근제어자(Access Modifiers)는 객체 지향 프로그래밍에서 클래스의 멤버(변수,메소드 등)에 대한 접근 권한을 제한하는 키워드입니다. 데이터를 은닉하고 캡슐화를 할 수 있어 객체 지향 프로그래밍에서 중요한 역할을 합니다.
주요 접근 제어자는 아래와 같습니다.
- public: 멤버가 모든 클래스에서 접근 가능하도록 한다. 가장 개방적인 수준
- protected: 멤버가 선언된 클래스와 그 서브 클래스에서만 접근 가능합니다.
- private: 멤버가 선언된 클래스 내에서만 접근 가능하다. 가장 제한적인 접근 수준으로, 외부에서는 해당 멤버에 접근할 수 없어 클래스의 내부 구현을 숨길 때 사용합니다.
우선 예제를 통해 접근 제한자의 개념을 살펴보겠습니다.
class Dog(private val dogSize: String) { private var barkSound = "멍!" var age = 0 fun say():String { when(dogSize) { "big" -> barkSound = "에푸!" "medium" -> barkSound = "멍!" "small" -> barkSound = "낑!" else -> barkSound = "전 개가 아닙니다" } return barkSound } } fun main() { val 대형견 = Dog("big") 대형견.age = 4 //error 대형견.barkSound = "낑!" //error println(대형견.barkSound) // -> barkSound 호출불가 private 접근제어자 때문에 오류 발생 println(대형견.say()) // -> "에푸!"출력
위 코드에서는 Dog 클래스를 정의했습니다. Dog 클래스에는 클래스 외부에서 접근할 수 없는 private 변수 barkSound가 있습니다. age는 public으로 정의되었습니다. 코틀린에서는 접근 제어자를 명시하지 않으면 암시적으로 public으로 간주됩니다.
main 함수에서 두 변수를 수정하려고 할 때, age는 public이므로 문제없이 접근할 수 있지만, barkSound는 private이므로 접근할 수 없어 오류가 발생합니다.
접근 제한자 사용하는 이유
- 데이터 캡슐화: 클래스의 내부 구현을 외부에 숨길 수 있어 정보 은닉이 가능합니다.
- 유지보수성 향상: 클래스 내부 구현을 변경해도 외부 코드에 미치는 영향을 최소화할 수 있습니다.
- 코드 안전성 향상: 잘못된 접근을 막아 오류를 예방할 수 있습니다.
접근 제어자를 사용하지 않았을 때
class Dog(private val dogSize: String) { var barkSound = "멍!" var age = 0 fun say():String { when(dogSize) { "big" -> barkSound = "에푸!" "medium" -> barkSound = "멍!" "small" -> barkSound = "낑!" else -> barkSound = "전 개가 아닙니다" } return barkSound } } fun main() { val 대형견 = Dog("big") 대형견.barkSound = "에푸!" println(대형견.barkSound) println(대형견.say()) } fun main2() { val 리트리버 = Dog("big") 리트리버.barkSound = "에푸!" ... }
위 코드에서는 barkSound를 public으로 설정하여 어디서든 접근 가능하게 만들었습니다. 만약 대형견의 울음소리를 "왈!왈!"로 변경해야 하는 상황이 발생한다면, say() 함수를 사용하는 부분은 Dog 클래스 내부 로직만 수정하면 되지만, barkSound를 직접 변경한 부분은 일일이 찾아서 수정해야 합니다.
그렇다면 barkSound는 클래스 외부에서 전혀 사용할 수 없을까요?
main 함수에서 println(대형견.barkSound)를 사용하면 barkSound에 접근할 수 없어 오류가 발생합니다. 하지만 클래스 내부 함수인 say()를 사용하면 barkSound의 값을 가져올 수 있습니다. say()는 public 함수이기 때문에 클래스 외부에서 호출하여 barkSound의 값을 간접적으로 얻을 수 있습니다.
보안이 중요한 은행 프로그램의 경우를 생각해 보겠습니다:
class BankAccount( var accountNumber: String, var balance: Int ) { fun deposit(amount: Int) { if (amount > 0) { balance += amount println("$amount 원이 입금되었습니다.") } else { println("입금 금액이 잘못되었습니다.") } } fun withdraw(amount: Int) { if (amount > 0 && amount <= balance) { balance -= amount println("$amount 원이 출금되었습니다.") } else { println("출금 금액이 잘못되었거나 잔액이 부족합니다.") } } fun checkBalance() { println("현재 잔액: $balance 원") } } fun main() { val account = BankAccount("123-456-7890", 1000000) // 계좌 정보 직접 변경 account.balance = 10000000000 // 잔액을 변경 가능 // 거래 내역 조작 account.deposit(500000) account.withdraw(2000000) // 잔액보다 많은 금액 인출 가능 account.checkBalance() // 조작된 잔액 출력 }
위 코드에서는 계좌의 잔액을 외부에서 변경할 수 있어 거래 내역을 조작하고, 원래 잔액보다 많은 금액을 인출하는 등의 보안 문제가 발생할 수 있습니다. 은행 시스템에서는 사용자가 입금, 출금 등의 작업을 수행할 때만 해당 로직에 접근할 수 있어야 합니다. 데이터를 전송하고 처리하는 구간에서도 접근하여 데이터를 조작할 수 있다면 심각한 문제가 될 수 있습니다.
따라서 중요한 데이터를 안전하게 관리하고, 코드의 안전성과 유지보수성을 높이기 위해 접근 제어자를 사용하는 것이 좋습니다.
내일배움캠프는 개발에 필요한 핵심만 배웁니다
지금까지 꼭 필요한 개발 지식에 대해 알아보았습니다. 내일배움캠프에서는 전문가들이 선별한 핵심 개발 지식으로 개발 공부도, 취업도 보다 효율적으로 할 수 있는데요. 국내 유수의 IT기업 출신 튜터님들과 실습 위주의 독보적인 커리큘럼으로 개발자 취업을 체계적으로 준비해보세요. 내일배움캠프 4개월, 여러분 인생의 가장 큰 터닝 포인트입니다.
CREDIT
글 | 심규상 내일배움캠프 수료생
편집 | 정효재 팀스파르타 에디터
취업 준비, 어디서부터 시작해야 할지 모르겠다면?
🧐비전공자인데 IT 업계 취업할 수 있을까?
😟프로젝트 경험이 부족한데, 어떻게 준비해야 할까?
🥺IT 기업으로 이직하고 싶은데 뭐부터 시작해야 할까?
이런 고민을 하고 있다면, 내일배움캠프의 IT 취업 컨설팅을 받아보세요.
취업 코칭 전문가들이 여러분의 고민을 해결해 드립니다.
다음 링크에 이메일을 입력하시면 메일로 1:1 커리어 상담권과 취준 자료집을 보내드릴게요.
Share article
Subscribe to our newsletter