REC

[w7] 객체지향 프로그래밍 특징: 캡슐화, 추상화, 다형성, 상속 본문

SKALA

[w7] 객체지향 프로그래밍 특징: 캡슐화, 추상화, 다형성, 상속

서서리 2025. 9. 2. 22:26
SMALL

캡슐화

  • 객체 내부의 데이터와 메서드를 하나로 묶어 → 1) 외부로부터 직접 접근하지 못하도록 숨기고, 2) 공개된 인터페이스를 통해서만 접근할 수 있도록 하는 개념.
  • 객체 내부의 상태를 보호하고, 데이터 무결성을 유지하며, 복잡한 내부 구현을 외부로부터 은닉할 수 있다.
  • ⇒ 각 객체 고유의 독립성과 책임 영역을 안전하게 지키고자 하는 목적이다.
public class BankAccount {
		
    // 데이터 캡슐화
    private double balance = 0.0;

    public BankAccount(double balance) {
        // 데이터 검증
        if (balance > 0) {
            this.balance = balance;
        }
    }

    public void deposit(double amount) {
        // 데이터 검증
        if (amount > 0) {
            this.balance += amount;
        }
    }

    public boolean withdraw(double amount) {
        // 데이터 검증
        if (amount > 0 && amount <= balance) {
            this.balance -= amount;
            return true;
        } else {
            return false;
        }
    }

    public double getBalance() {
        return this.balance;
    }
}

상속

  • 기존 클래스(부모)의 속성과 메서드를 새로운 클래스(자식)가 물려받아 재사용하고 확장할 수 있는 기능.
  • 추상화 수준을 높여 객체의 계층적 분류를 가능하게 한다.
  • 코드 중복을 줄이고, 소프트웨어의 유지보수성과 확장성을 향상시킬 수 있다.
  • ⇒ IS-A 관계가 성립할 때 사용해야 한다. 재사용이 목적이 아닌 기능의 확장이 목적이다.
// 부모 클래스
class Animal {

    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    void sound() {
        System.out.println("동물이 소리를 낸다.");
    }
}

// 자식 클래스 (상속)
class Dog extends Animal {

    public Dog(String name) {
        super(name);
    }

    @Override
    void sound() {
        System.out.println(name + "은(는) 멍멍 짖는다.");
    }
}

public class Main {

    public static void main(String[] args) {
        Dog myDog = new Dog("보리");
        myDog.sound(); // 보리는(은) 멍멍 짖는다.
    }
}

추상화

  • 복잡한 시스템에서 불필요한 세부사항을 숨기고, 중요한 특징이나 속성만을 추출해 단순화하는 개념.
  • 즉, 현실 세계의 복잡한 객체나 상황을 모델링할 때 핵심적인 부분만을 표현하여 설계나 이해를 쉽게 만든다.
  • ⇒ 세부적인 사물들의 공통적 특징을 파악한 후 하나의 묶음으로 만들어내는 것으로, 역할과 구현을 분리하고자 하는 목적이다.
// 공통 행위 정의 -> 추상화
interface Animal {
    void makeSound();
}

// 구체 구현 1
class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("멍멍");
    }
}

// 구체 구현 2
class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("야옹");
    }
}

public class Main {

    static void playSound(Animal animal) {
        animal.makeSound();
    }

    public static void main(String[] args) {
        Animal myDog = new Dog();
        Animal myCat = new Cat();

        playSound(myDog); // 멍멍
        playSound(myCat); // 야옹
    }
}

다형성

  • 동일한 인터페이스를 사용하지만 서로 다른 타입의 객체들이 각기 다른 방식으로 동작할 수 있게 하는 능력.
  • 같은 메세지(메서드 호출)에 대해 객체별로 다양하게 대응할 수 있게 하여 유연한 코드를 작성할 수 있다.
  • ⇒ 역할과 구현을 구분해 객체들 간의 직접적 결합을 피하고, 느슨한 관계를 설정하고자 하는 목적이다.
// 부모 클래스 (공통 인터페이스(행동)를 제공)
class Animal {

    void makeSound() {
        System.out.println("동물이 소리를 낸다.");
    }
}

// 자식 클래스 1
class Dog extends Animal {

    @Override
    void makeSound() {
        System.out.println("멍멍");
    }
}

// 자식 클래스 2
class Cat extends Animal {

    @Override
    void makeSound() {
        System.out.println("야옹");
    }
}

public class Main {

    public static void main(String[] args) {
        // 참조 타입은 모두 Animal이지만, 각각의 실제 객체는 Dog, Cat, Animal
        Animal[] animals = {new Dog(), new Cat(), new Animal()};

        for (Animal animal : animals) {
            // 런타임에 각 객체에 맞는 행동이 실행된다.
            animal.makeSound(); // 멍멍
                                // 야옹
                                // 동물이 소리를 낸다.
        }
    }
}

Last Modified : 2025.09.01

LIST