[cs 스터디] 1-2. 프로그래밍 패러다임 - 객체지향 프로그래밍

YooJeeun·2024년 12월 26일

cs 스터디

목록 보기
11/65

객체지향 프로그래밍

객체지향 프로그래밍(Object-Oriented Programming, OOP)은 객체들의 집합을 통해 프로그램의 상호작용을 표현하고, 데이터를 객체로 취급하여 해당 객체 내부에 선언된 메서드를 활용하는 프로그래밍 방식이다. 객체지향 설계는 시간이 많이 소요될 수 있으며, 실행 속도는 다른 프로그래밍 패러다임에 비해 느릴 수 있다.

자연수로 이루어진 배열에서 최댓값을 찾으라고 한다면 다음과같이 로직을 구성한다.

const ret = [1, 2, 3, 4, 5, 11, 12]
class List {
    constructor(list) {
        this.list = list
        this.mx = list.reduce((max, num) => num > max ? num : max, 0)
    }
    getMax() {
        return this.mx
    }
}
const a = new List(ret)
console.log(a.getMax()) // 12

List클래스는 배열을 받아 최댓값을 구하는 로직을 캡슐화한다.
이를 통해 객체를 통해 필요한 작업을 수행할 수 있다.

객체지향 프로그래밍의 주요 특징

  1. 추상화(Abstraction)
    복잡한 시스템에서 핵심 개념만 추려내는 작업
  2. 캡슐화(Encapsulation)
    객체의 속성과 메서드를 하나로 묶고, 외부에서 접근할 수 없도록 일부를 은닉하는 것
  3. 상속성(Inheritance)
    상위 클래스의 특성을 하위 클래스가 물려받아 확장하거나 재사용하는 개념
    class Animal {
       public void sound() {
           System.out.println("Some sound");
       }
    }
    class Dog extends Animal {
       @Override
       public void sound() {
           System.out.println("Bark");
       }
    }
  4. 다형성(Polymorphism)
    같은 이름의 메서드가 다양한 방식으로 동작할 수 있도록 하는 기능
    다형성은 오버로딩(컴파일 시점)과 오버라이딩(런타임 시점)으로 구현된다.
오버로딩

오버로딩(overloading)은 같은 이름을 가진 메서드를 여러 개 두는 것을 말한다. 메서드의 타입, 매개변수의 유형, 개수 등으로 여러 개를 둘 수 있으며 컴파일 중에 발생하는 '정적' 다형성이다.

class Person {

    public void eat(String a) {
        System.out.println("I eat " + a);
    }

    public void eat(String a, String b) {
        System.out.println("I eat " + a + " and " + b);
    }
}

public class CalculateArea {

    public static void main(String[] args) {
        Person a = new Person();
        a.eat("apple");
        a.eat("tomato", "phodo");
    }
}
/*
I eat apple
I eat tomato and phodo
*/

매개 변수의 개수에 따라 다른 함수가 호출되는 것을 알 수 있다.

오버라이딩

오버라이딩(overriding)은 주로 메서드 오버라이딩을 말하며 상위 클래스로부터 상속받은 메서드를 하위 클래스가 재정의하는 것을 의미한다.
이는 런타임중에 발생하는 '동적' 다형성이다.

class Animal {
    public void bark() {
        System.out.println("mumu! mumu!");
    }
}

class Dog extends Animal {
    @Override
    public void bark() {
        System.out.println("wal!!! wal!!!");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.bark();
    }
}
/*
wal!!! wal!!!
*/

자식 클래스 기반으로 메서드가 재정의됨을 알 수 있다.

SOLID 설계 원칙

객체지향 설계에서 SOLID 원칙은 코드의 유지보수성과 확장성을 보장하기위해 반드시 지켜야할 기준이다.

  1. 단일 책임 원칙(SRP, Single Responsibility Principle)
    클래스는 단 하나의 책임만 가져야 한다.

  2. 개방-폐쇄 원칙(OCP, Open Closed Principle)
    코드는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 한다. 즉 기존 코드는 잘 변경하지 않으면서 확장은 쉽게 할 수 있어야 한다.

  3. 리스코프 치환 원칙(LSP, Liskov Substitution Principle)
    하위 타입은 상위타입으로 대체 가능해야 한다.

  4. 인터페이스 분리 원칙(ISP, Interface Segregation Principle)
    하나의 일반 인터페이스보다 구체적인 여러 인터페이스로 나누어야 한다.

  5. 의존 역전 원칙(DIP, Dependency Inversion Principle)
    상위 계층은 하위 계층에 의존하지 않고, 추상화된 인터페이스에 의존해야 한다.
    예를 들어 타이어를 교체할 수 있는 인터페이스를 설계하면 다양한 종류의 타이어로 교체가 가능하다.

    interface Tire {
       void rotate();
    }
    class Car {
       private Tire tire;
    
       public Car(Tire tire) {
           this.tire = tire;
       }
    
       public void drive() {
           tire.rotate();
       }
    }
profile
제니벨로그

0개의 댓글