캡슐화란?
캡슐화( Encapsulation)는 데이터(속성)와 메서드(행위)를 하나의 단위로 묶어 외부에서의 접근을
제한하는 객체지향 프로그래밍의 주요 개념 중 하나이다.
- 데이터 보호와 접근 제어를 통해 데이터의 무결성을 보장한다.
- 외부 객체는 캡슐화된 객체 내부의 데이터를 직접 수정하거나 접근할 수 없으며,
객체가 제공하는 메서드(인터페이스)를 통해서만 상호작용 가능하다.
캡슐화의 특징
- 데이터 은닉:
- 외부에서 객체의 **필드(변수)**에 직접 접근하지 못하도록 제한한다.
- 일반적으로 필드는 private으로 선언하고, 필요한 경우 메서드를 통해 접근한다.
- 메서드를 통한 접근:
- 데이터를 조작하거나 읽는 데 필요한 메서드(Getter, Setter)를 제공한다.
- 메서드 내부에서 입력값 검증 및 데이터 처리 로직을 추가할 수 있다.
- 독립성:
- 객체 내부 구현을 숨기고, 외부에 필요한 기능만 노출하여 코드의 독립성을 높인다.
- 내부 구현 변경 시 외부 코드에 영향을 주지 않는다.
캡슐화의 장점
데이터 무결성 보장:
- 잘못된 데이터를 입력하거나 수정하는 것을 방지한다.
- Setter 메서드에서 유효성 검사를 수행할 수 있다.
코드 변경 용이성:
- 클래스 내부 구현이 변경되어도 외부에 제공되는 인터페이스(Getter, Setter)가 동일하면
외부 코드에 영향을 미치지 않는다.
데이터 은닉:
- 외부 객체는 캡슐화된 데이터에 직접 접근할 수 없으므로 데이터를 보호할 수 있다.
객체 지향 원칙 준수:
- 정보 은닉(Information Hiding)과 모듈화(Modularity)를 통해 객체지향 설계 원칙을 구현한다.
재사용성 증가:
- 캡슐화된 클래스는 독립적이고 안정적이므로 재사용 가능성이 높아진다.
캡술화 구현
- 필드(변수) 접근 제한:
- private 접근 제어자를 사용해 데이터를 숨긴다.
- private 접근 제어자를 사용해 데이터를 숨긴다.
- Getter와 Setter 메서드 제공:
- public 메서드로 외부에서 데이터를 읽거나 수정할 수 있도록 한다.
- 메서드 내부에서 데이터 유효성을 검사할 수 있다.
- 단일 책임 원칙 (SRP):
- 캡슐화는 클래스의 내부 구현과 외부 인터페이스를 분리해 한 가지 책임만 가지도록 설계한다.
- 캡슐화는 클래스의 내부 구현과 외부 인터페이스를 분리해 한 가지 책임만 가지도록 설계한다.
- 개방-폐쇄 원칙 (OCP):
- 클래스 내부를 수정하지 않고도 새로운 기능을 추가할 수 있다.
캡슐화 전: 데이터 노출
public class Person {
public String name; // 외부에서 직접 접근 가능
public int age;
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
person.name = "Alice"; // 데이터 직접 수정
person.age = -5; // 잘못된 데이터 입력
System.out.println(person.name + ", " + person.age);
}
}
캡슐화 적용 후: 데이터 보호
public class Person {
private String name; // 데이터 은닉
private int age;
// Getter
public String getName() {
return name;
}
// Setter
public void setName(String name) {
this.name = name;
}
// Getter
public int getAge() {
return age;
}
// Setter (유효성 검사 추가)
public void setAge(int age) {
if (age > 0) { // 나이는 0보다 커야 함
this.age = age;
} else {
System.out.println("Invalid age!");
}
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
// 데이터 설정
person.setName("Alice");
person.setAge(-5); // 잘못된 데이터, 유효성 검사로 방지
// 데이터 출력
System.out.println(person.getName() + ", " + person.getAge());
}
}
Getter와 Setter의 추가 활용
입력값 검증
public void setAge(int age) {
if (age > 0 && age < 150) { // 유효한 나이 범위 확인
this.age = age;
} else {
throw new IllegalArgumentException("Age must be between 1 and 150");
}
}
읽기 전용 필드
필드 값을 읽을 수만 있고 변경할 수 없도록 Getter만 제공.
public String getName() {
return name;
}
쓰기 전용 필드
필드 값을 외부에서 설정만 가능하고 읽을 수 없도록 Setter만 제공.
public void setPassword(String password) {
this.password = password;
}
실제 예제 (은행 계좌)
public class BankAccount {
private String accountNumber; // 계좌번호
private double balance; // 잔액
// 생성자
public BankAccount(String accountNumber) {
this.accountNumber = accountNumber;
this.balance = 0; // 초기 잔액은 0
}
// Getter
public String getAccountNumber() {
return accountNumber;
}
public double getBalance() {
return balance;
}
// 입금 메서드 (입금 금액 유효성 검사)
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
} else {
System.out.println("Invalid deposit amount!");
}
}
// 출금 메서드 (잔액 부족 확인)
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
} else {
System.out.println("Insufficient balance or invalid amount!");
}
}
}
public class Main {
public static void main(String[] args) {
BankAccount account = new BankAccount("123-456-789");
account.deposit(1000); // 1000 입금
account.withdraw(500); // 500 출금
System.out.println("Balance: " + account.getBalance()); // 출력: 500
}
}
'Java' 카테고리의 다른 글
Java 람다식 (Lambda Expression) (0) | 2024.11.18 |
---|---|
Java 클래스와 메서드, 객체 (Class, Object, Method) (1) | 2024.11.16 |
Java 반복문 (for, while, do while, 다중 반복문) (1) | 2024.11.15 |
Java 조건문 (if, if else, switch case) (0) | 2024.11.14 |
Java 문자열 (String) (1) | 2024.11.14 |