오늘의 질문
객체 지향 프로그래밍이란 무엇이고, 어떤 특징이 있나요?

객체 지향 프로그래밍 (OOP, Object-Oriented Programming)

상태(필드)와 행위(메서드)를 가진 객체를 중심으로 프로그램을 설계하는 프로그래밍 패러다임이다. 객체에 역할과 책임을 부여하고, 이 객체들이 서로 협력하는 방식으로 프로그램을 구성한다.

객체 지향 프로그램의 특징

캡슐화 (Encapsulation)

객체의 상태와 행위를 하나의 단위로 묶는다. 내부 구현은 숨기고 외부에서 접근할 수 있는 인터페이스만 제공함으로써 객체의 무결성을 보호하고 코드의 유지보수성을 높일 수 있다.


추상화 (Abstraction)

불필요한 세부 사항을 감추고 핵심적인 기능만 간추리는 것을 말한다. 객체의 공통적인 특징은 추출하여 인터페이스 또는 추상 클래스로 정의하고 구체적인 세부 사항은 구현체에게 위임함으로써 객체의 핵심 기능에만 집중할 수 있다.


다형성 (Polymorphism)

하나의 인터페이스가 여러 형태르 동작할 수 있는 것을 말한다. 오버로딩과 오버라이딩을 사용하여 같은 메서드 명이더라도 객체에 따라 다른 방식으로 동작하도록 할 수 있다.


상속 (Inheritance)

상위 클래스의 특징을 하위 클래스가 물려받아 확장하는 것을 말한다. 기존 기능을 수정하지 않고 새로운 기능을 추가할 수 있어 확장성이 뛰어나고, 중복을 제거하여 코드의 재사용성을 높일 수 있다.


TDA 원칙

TDA(Tell Don’t Ask) 원칙은 객체의 데이터를 직접 요청하지 말고 객체에게 필요한 동작을 수행하도록 메시지를 보내라는 원칙이다. TDA 원칙에 따르면 캡슐화를 지킬 수 있고, 객체 스스로 데이터를 다루기 때문에 객체의 응집도를 높이고 객체 간 결합도를 낮출 수 있다.

// 준수 예시 (Good)
public class Account {

    private BigDecimal balance;

    public Account(BigDecimal balance) {
        this.balance = balance;
    }

    public void withdraw(BigDecimal withdrawalAmount) {
        if (balance.compareTo(withdrawalAmount) < 0) {
            throw new IllegalStateException("잔액이 부족합니다.");
        }
        this.balance = balance.subtract(withdrawalAmount);
    }
}

Account account = new Account(BigDecimal.TEN);
BigDecimal withdrawalAmount = BigDecimal.ONE;

account.withdraw(withdrawalAmount); // 객체에 메시지 전달
// 위반 예시 (Bad)
public class Account {

    private BigDecimal balance;
    
    public Account(BigDecimal balance) {
        this.balance = balance;
    }

    public BigDecimal getBalance() {
        return this.balance;
    }
    
    public void setBalance(BigDecimal balance) {
        this.balance = balance;
    }
}

Account account = new Account(BigDecimal.TEN);
BigDecimal withdrawalAmount = BigDecimal.ONE;

BigDecimal balance = account.getBalance(); // 객체의 데이터를 직접 가져와서 사용
if (balance.compareTo(withdrawalAmount) < 0) {
    throw new IllegalStateException("잔액이 부족합니다.");
}

balance = balance.subtract(withdrawalAmount);
account.setBalance(balance);

추상 클래스와 인터페이스의 차이

추상 클래스는 공통된 기능을 재사용하려는 목적으로 사용된다. 일반 메서드와 추상 메서드를 포함할 수 있고, 인스턴스 변수를 가질 수 있다. 인터페이스는 구현을 강제하려는 목적으로 사용된다. 추상 메서드와 상수만 가질 수 있다. 코드의 재사용이 중요한 경우 추상 클래스를 사용하고, 다중 상속이 필요한 경우 인터페이스를 사용한다.


🔖 참고자료

매일메일