캡슐화(Encapsulation)
캡슐화는 객체의 데이터와 해당 데이터를 조작하는 기능을 하나의 단위로 묶고, 내부 구현을 외부로부터 숨기는 메커니즘입니다.
주요 목표
- 데이터 무결성 보장: 외부의 잘못된 접근으로부터 내부 상태를 보호
- 모듈 독립성 향상: 인터페이스와 구현의 분리로 변경 영향도 최소화
- 재사용성 극대화: 검증된 컴포넌트를 여러 곳에서 활용
구현 방식
접근 제어자를 활용해 필드의 직접 접근을 차단하고, 제어된 통로인 접근자 메서드를 제공합니다.
public class Member {
private String username;
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 0) {
this.age = age;
}
}
}
상속(Inheritance)
상속은 기존 클래스의 특성을 이어받아 새로운 클래스를 구성하는 방법론으로, 코드 중복 제거와 계층적 설계를 가능하게 합니다.
핵심 가치
- 중복 코드 제거: 공통 기능의 중앙 집중化管理
- 계층 구조 명확화: 개념적 포함 관계(예: 고양이는 포유류의 일종)를 코드로 표현
- 다형성의 토대 마련: 일관된 인터페이스를 통한 유연한 설계 기반
구현 예시
class Vehicle {
void accelerate() {
System.out.println("차량이 가속합니다");
}
}
class Bicycle extends Vehicle {
void ringBell() {
System.out.println("따르릉");
}
}
제약사항
- Java: 단일 상속만 허용(다중 상속은 인터페이스로 대체)
- 계층의 깊이는 제한 없이 확장 가능
- 다수의 인터페이스 동시 구현은 가능
다형성(Polymorphism)
동일한 메시지에 대해 객체의 실제 타입에 따라 각기 다른 반응을 보이는 능력입니다.
Java에서의 필수 조건
- 상위-하위 관계(상속 또는 인터페이스 구현) 존재
- 하위 클래스에서 메서드 재정의(오버라이딩)
- 상위 타입 참조변수가 하위 타입 인스턴스를 가리킴
활용 예시
abstract class Employee {
abstract void performDuty();
}
class Developer extends Employee {
@Override
void performDuty() {
System.out.println("코드 작성 및 시스 설계");
}
}
class Designer extends Employee {
@Override
void performDuty() {
System.out.println("UI/UX 설계 및 프로토타입 제작");
}
}
public class RuntimePolymorphism {
public static void main(String[] args) {
Employee[] staff = { new Developer(), new Designer() };
for (Employee member : staff) {
member.performDuty();
}
}
}
Java와 Python의 다형성 비교
두 언어의 근본적인 차이(정적 타입 vs 동적 타입)는 다형성 구현 방식에도 반영됩니다.
| 비교 항목 | Java | Python |
|---|---|---|
| 계층 관계 필수 여부 | 상속/구현 관계 필수 | 선택적; 덕 타이핑으로 대체 가능 |
| 메서드 재정의 규칙 | 엄격(시그니처 일치, @Override 권장) | 유연(동일 이름만 충족) |
| 참조 타입 바인딩 | 컴파일 타임 타입 선언 필요 | 런타임에 타입 결정, 선언 불필요 |
Python의 덕 타이핑 예시:
class Writer:
def create(self):
print("문서를 작성합니다")
class Painter:
def create(self):
print("그림을 그립니다")
def start_project(worker):
worker.create()
# 동일한 인터페이스, 서로 다른 클래스
start_project(Writer())
start_project(Painter())