Gapus Dev Blog

[CS] 객체 지향 프로그래밍(Object-Oriented Programming)에 대해 본문

CS

[CS] 객체 지향 프로그래밍(Object-Oriented Programming)에 대해

Gapus 2023. 11. 18. 08:00

객체 지향 프로그래밍(OOP)


설명

  • 프로그램을 객체들의 집합으로 구성하는 방식
  • 객체들은 데이터와 그 데이터를 처리하는 메서드를 포함
  • 객체 간에 상호작용을 통해 프로그램이 동작

주요 특징

 

클래스와 객체

  • 클래스는 객체를 만들기 위한 템플릿
  • 객체는 클래스로부터 생성된 실체
  • 클래스는 객체의 속성(데이터)과 동작(메서드)을 정의하고, 객체는 이러한 속성과 동작을 가진다.
  • 클래스는 설계도 역활, 객체는 설계도를 기반으로 생성된 실체
  • 예시
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sayHello() {
    console.log(`안녕하세요, 저는 ${this.name}이고 ${this.age}살입니다.`);
  }
}

let person1 = new Person("John", 25);
person1.sayHello(); // "안녕하세요, 저는 John이고 25살입니다."

 

캡슐화(Encapsulation)

  • 관련된 데이터와 메서드를 하나의 객체로 묶어 캡슐화
  • 데이터의 접근을 제한하고, 객체 내부의 동작을 캡슐화하여 외부에서는
    객체의 내부 동작 방식을 확인하지 못하게 함
  • 예시
class Car {
  constructor(color, model) {
    this.color = color;
    this.model = model;
    this.fuel = 100;
  }

  accelerate() {
    console.log("가속합니다.");
  }

  brake() {
    console.log("제동합니다.");
  }

  startEngine() {
    console.log("시동을 켭니다.");
  }
}

let myCar = new Car("Red", "Sedan");
console.log(myCar.color); // "Red"
console.log(myCar.model); // "Sedan"
myCar.accelerate(); // "가속합니다."
myCar.brake(); // "제동합니다."

 

상속(Inheritance)

  • 부모 클래스의 특징을 자식 클래스가 물려받는 상속 개념을 지원
  • 상속을 통해 재사용성을 높이고, 계층적인 구조를 구성
  • 예시
class Animal {
  constructor(name) {
    this.name = name;
  }

  eat() {
    console.log(this.name + "이(가) 먹이를 먹습니다.");
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  bark() {
    console.log(this.name + "이(가) 짖습니다.");
  }
}

let myDog = new Dog("맥스", "골든 리트리버");
console.log(myDog.name); // "맥스"
console.log(myDog.breed); // "골든 리트리버"
myDog.eat(); // "맥스이(가) 먹이를 먹습니다."
myDog.bark(); // "맥스이(가) 짖습니다."

 

다형성(Polymorphism)

  • 같은 이름의 메서드를 다양한 객체에서 다르게 구현할 수 있는 다형성 개념 지원
  • 객체의 타입에 따라 다른 동작을 수행
  • 예시
class Shape {
  constructor() {}

  calculateArea() {
    console.log("도형의 넓이를 계산합니다.");
  }
}

class Rectangle extends Shape {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
  }

  calculateArea() {
    console.log("사각형의 넓이를 계산합니다.");
    return this.width * this.height;
  }
}

class Circle extends Shape {
  constructor(radius) {
    super();
    this.radius = radius;
  }

  calculateArea() {
    console.log("원의 넓이를 계산합니다.");
    return Math.PI * this.radius * this.radius;
  }
}

let shapes = [new Rectangle(4, 5), new Circle(3)];
shapes.forEach(shape => {
  console.log(shape.calculateArea());
});

 

추상화(Abstraction)

  • 객체에서 공통된 속성과 동작을 추출하여 클래스로 정의하는 과정
  • 객체 지향 프로그래밍에서는 필요한 기능과 속성을 추상화하여 클래스로 정의, 이를 기반으로 객체를 생성
  • 예시
class Vehicle {
  constructor(name) {
    this.name = name;
  }

  start() {
    throw new Error("start 메서드는 하위 클래스에서 구현되어야 합니다.");
  }

  stop() {
    throw new Error("stop 메서드는 하위 클래스에서 구현되어야 합니다.");
  }
}

class Car extends Vehicle {
  start() {
    console.log(`${this.name}의 시동을 켭니다.`);
  }

  stop() {
    console.log(`${this.name}의 시동을 끕니다.`);
  }
}

class Motorcycle extends Vehicle {
  start() {
    console.log(`${this.name}의 엔진을 가동합니다.`);
  }

  stop() {
    console.log(`${this.name}의 엔진을 정지합니다.`);
  }
}

let car = new Car("자동차");
car.start(); // "자동차의 시동을 켭니다."
car.stop(); // "자동차의 시동을 끕니다."

let motorcycle = new Motorcycle("오토바이");
motorcycle.start(); // "오토바이의 엔진을 가동합니다."
motorcycle.stop(); // "오토바이의 엔진을 정지합니다."

 


상속과 메서드 오버라이딩

  • 상속 관계에서 자식 클래스가 부모 클래스의 메서드를 재정의
  • 과정
    1. 자식 클래스에서 부모 클래스와 동일한 이름의 메서드를 정의
    2. 자식 클래스의 메서드가 부모 클래스의 메서드를 덮어씌우게 된다.
    3. 자식 클래스에서는 부모 클래스의 메서드를 재정의하여 자신의 동작을 구현
  • 예시
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name}이 소리를 냅니다.`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  speak() {
    console.log(`${this.name}이 짖습니다.`);
  }
}

let dog1 = new Dog("맥스", "골든 리트리버");
dog1.speak(); // "맥스이 짖습니다."

 

 

다형성과 메서드 오버로딩

  • 동일한 이름을 가진 메서드를 매개변수의 개수나 타입에 따라 다르게 정의
  • 자바스크립트는 메서드 오버로딩을 명식적으로 지원하지 않지만,
    매개변수의 개수나 타입을 확인하여 다른 동작을 수행
  • 동일한 기능을 수행하는 메서드를 간결하게 정의하고 사용할 수 있도록 도움
  • 예시
class Shape {
  calculateArea() {
    console.log("도형의 넓이를 계산합니다.");
  }
}

class Rectangle extends Shape {
  calculateArea(width, height) {
    console.log(`사각형의 넓이는 ${width * height}입니다.`);
  }
}

class Circle extends Shape {
  calculateArea(radius) {
    console.log(`원의 넓이는 ${Math.PI * radius * radius}입니다.`);
  }
}

let rectangle = new Rectangle();
rectangle.calculateArea(4, 5); // "사각형의 넓이는 20입니다."

let circle = new Circle();
circle.calculateArea(3); // "원의 넓이는 28.274333882308138입니다."

 


 

객체 지향 프로그래밍(OOP)과 절차 지향 프로그래밍의 차이점

 

프로그래밍 중심

  • 절차 지향 프로그래밍
    • 절차 지향 프로그래밍은 프로그램을 처리해야 할 일의 목록으로 간주
    • 프로그램의 주요 구성 요소는 함수 또는 프로시저
    • 함수들은 데이터를 처리하고, 필요한 경우에 다른 함수를 호출하여 작업을 수행
  • 객체 지향 프로그래밍
    • 프로그램을 상호작용하는 객체들의 집합
    • 객체는 데이터와 해당 데이터를 처리하는 메서드를 포함
    • 객체들 간의 상호작용을 통해 프로그램이 동작

 

데이터와 메서드 캡슐화

  • 절차 지향 프로그래밍
    • 데이터와 해당 데이터를 처리하는 함수가 분리되어 있으며, 데이터에 대한 접근이 자유롭다.
  • 객체 지향 프로그래밍
    • 데이터와 해당 데이터를 처리하는 메서드를 하나의 단위로 캡슐화
    • 데이터에 대한 접근을 제한하고, 객체 내부의 동작을 캡슐화하여 외부에서는 내부 동작 방식을 알 수 없게 함.

 

상속과 다형성

  • 절차 지향 프로그래밍
    • 상속과 다형성 없음
    • 코드의 재사용성과 유연성이 상대적으로 낮음
  • 객체 지향 프로그래밍
    • 상속과 당형성 개념 지원
    • 상속을 지원하여 코드의 재사용성과 확장성 향상
    • 다형성을 지원하여 객체의 타입에 따라 다른 동작을 수행 가능

 

추상화

  • 절차 지향 프로그래밍
    • 데이터와 함수를 분리하여 프로그램을 구성하기 떄문에 추상화 수준이 낮을 수 있음.
  • 객체 지향 프로그래밍
    • 추상화를 통해 객체들의 공통된 속성과 동작을 추출하여 클래스로 정의
    • 추상화를 통해 객체의 복잡한 세부 내용을 단순화하고 모델링 가능