객체지향 프로그래밍은 개발자에게 친숙하면서도 때로는 어려운 개념이지만, 반드시 이해하고 넘어가야 할 중요한 개념이다. 이 시리즈에서는 객체지향 프로그래밍의 탄생 배경을 시작으로, 객체 지향 언어가 가진 객체지향 4대 특성을 알아보고, 객체지향 언어로 올바른 설계를 이루기 위한 SOLID 원칙을 살펴보겠다. 마지막으로, SOLID 원칙을 기반으로 한 객체지향 베스트 프랙티스인 디자인 패턴은 이후 다른 시리즈에서 자세히 다룰 예정이다.

 

 

객체지향 프로그래밍의 탄생 배경에 대해 알아보자

프로그래밍 언어는 개발자가 이해하고 다루기 쉽도록 점차 발전해 왔다. 초기에는 사람이 이해하기 어려운 기계어에서 시작해, 어셈블리어를 거쳐 절차지향 언어로 발전하며 사용 편의성이 개선되었지만, 여전히 기계 중심의 사고에 기반한 방식이었다. 그러던 중, "현실 세계를 바라보는 방식 그대로 프로그램을 작성할 수는 없을까?"라는 질문에서 객체지향 프로그래밍의 개념이 탄생했다. 사실, 우리가 살아가는 세상은 수많은 객체들, 즉 사물들의 상호작용으로 이루어져 있다. 우리가 보고, 만지고, 인식하는 모든 것을 객체로 정의할 수 있으며, 이 객체들이 서로 소통하고 협력하면서 현실세계의 다양한 현상을 만들어낸다. 이러한 객체의 개념을 프로그래밍에 도입한 것이 객체지향 프로그래밍이다. OOP를 통해 현실 세계를 더 직관적으로 모델링할 수 있게 되면서, 인간의 사고방식에 맞는 자연스러운 프로그램 설계가 가능해지게 되었다.

 

 

객체지향 사상을 잘 반영하는 언어는 무엇일까?

대표적인 객체지향 언어는 Java, Kotlin, C#, Ruby, Python 등이 있으며, 그 외에도 많은 언어들이 객체지향 사상을 반영하고 있다. 

 

그렇다면, 어떠한 기준으로 우리는 이러한 언어들을 객체지향 언어라고 부를 수 있을까? 절대적인 기준은 없지만, 오랜 세월에 걸쳐 정립된  객체 지향 4대 특성을 가지고 있다면 객체지향 언어라고 부를 수 있다. 그렇다면 객체 지향 4대 특성이 무엇이진 알아보자.

 

 

객체 지향 4대 특성이란?

객체지향 4대 특성에는 캡슐화, 상속, 추상화, 다형성이 있다. 객체지향 언어인 Java 예제 코드와 함께 알아보자.

 

1. 캡슐화

객체의 내부 구조를 감추고 외부에서는 필요한 인터페이스만 제공한다

public class BankAccount {
    private double balance; // 외부 접근 불가

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) balance += amount;
    }

    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) balance -= amount;
    }
}

 

 

2. 상속(확장)

기존의 클래스를 확장하여 새로운 클래스를 만드는 개념이다. 부모 클래스의 속성과 메서드를 자식 클래스가 물려받게 되고, 자식 클래스는 부모의 기능을 그대로 사용할 수 있고, 필요에 따라 확장하거나 재정의를 할 수 있다.

class Employee {
    protected String name;
    protected double salary;

    public void work() {
        System.out.println(name + " is working.");
    }
}

class Manager extends Employee {
    private int teamSize;

    public void manageTeam() {
        System.out.println(name + " is managing a team of " + teamSize);
    }
}

 

 

3. 추상화(모델링)

실제 사물을 정확히 복제하는 것이 아니라 목적에 맞게 관심 있는 특성만 추출해 단순하게 표현하는 것이다. 

// 추상 인터페이스: Database
interface Database {
    void connect();
    void disconnect();
    void executeQuery(String query);
}

// 구체적인 클래스: MySQLDatabase
class MySQLDatabase implements Database {
    @Override
    public void connect() {
        System.out.println("MySQL 데이터베이스에 연결합니다.");
    }

    @Override
    public void disconnect() {
        System.out.println("MySQL 데이터베이스 연결을 종료합니다.");
    }

    @Override
    public void executeQuery(String query) {
        System.out.println("MySQL에서 쿼리를 실행합니다: " + query);
    }
}

// 구체적인 클래스: OracleDatabase
class OracleDatabase implements Database {
    @Override
    public void connect() {
        System.out.println("Oracle 데이터베이스에 연결합니다.");
    }

    @Override
    public void disconnect() {
        System.out.println("Oracle 데이터베이스 연결을 종료합니다.");
    }

    @Override
    public void executeQuery(String query) {
        System.out.println("Oracle에서 쿼리를 실행합니다: " + query);
    }
}

 

 

4. 다형성

다형성은 객체가 여러 형태를 가질 수 있게 하는 개념으로, 상위 클래스 타입으로 하위 클래스의 객체를 참조하여 동일한 메서드를 호출할 때 다른 동작을 하도록 한다.

class Animal {
    public void sound() {
        System.out.println("Some sound...");
    }
}
class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("멍멍!");
    }
}
class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("야옹!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal[] animals = {new Dog(), new Cat()};
        for (Animal animal : animals) {
            animal.sound();
        }
    }
}
//(출력)
//멍멍!
//야옹!

 

 

정리

  • 객체지향 프로그래밍은 현실 세계를 바라보는 방식 그대로 프로그래밍하기 위해 탄생했다.
  • 객체지향 4대 특성을 가지는 언어를 객체지향 언어라고 한다. 
  • 객체 지향 4대 특성에는 캡슐화, 상속, 추상화, 다형성이 있다.
  • 다음 장에서는 객체지향 설계 5원칙인 SOLID에 대해 다루어 볼 것이다.

+ Recent posts