함수형으로만 개발하다가 OOP에 대해서 깊게 배울 때가 생겼습니다. 그 지식 습득에 대해 정리해보겠습니다.
다 읽어보시면 플라톤 철학과 OOP의 관계에 대해서도 읽어보세요. 신기한 개념이라 따로 정리해봤습니다.
객체는 데이터와 메소드의 집합으로, 현실의 개념이나 사물을 모델링한 프로그래밍의 기본 단위입니다. 객체는 속성(Property)과 동작(Method)을 가질 수 있으며, 다른 객체와 상호작용할 수 있습니다.
객체는 상태와 동작을 함께 가지지만, 함수는 주로 특정 동작만을 정의합니다.
객체 지향 프로그래밍(OOP)은 프로그램을 객체라는 기본 단위로 구성하는 방법론입니다. 주요 개념은 다음과 같습니다.
OOP 개념이 어렵다면 6살 짜리도 알 수 있는 객체를 참고해주세요. 비유적인 예시가 아주 탁월합니다.
OOP란 다시 말해, 데이터를 객체라는 단위로 묶어서 다루는 프로그래밍 패러다임입니다. 객체는 데이터(속성)와 해당 데이터의 동작(메소드)을 포함합니다.
과일의 특징을 모은 클래스를 만들 때, OOP의 4가지 개념을 적용해 보겠습니다. 속성은 과일 이름, 무게, 색상, 맛으로 제한하겠습니다.
JS는 기존 언어들의 OOP와는 많이 다른 모습을 보여주기에 TS로 예시를 보여주겠습니다.
먼저, 과일의 일반적인 속성과 동작을 정의(추상화)합니다. class Fruit
을 만듭니다.
class Fruit {
constructor(name: string, weight: number, color: string, taste: string) {
this.name = name; // 과일 이름
this.weight = weight; // 과일 무게
this.color = color; // 과일 색상
this.taste = taste; // 과일 맛
}
describe(): string {
return `${this.name}는 ${this.weight}g 무게를 가지고 있으며, ${this.color} 색상이고, 맛은 ${this.taste}입니다.`;
}
}
과일의 속성들을 클래스 내에 캡슐화합니다. 거기에 더해서 TS에서 private
키워드를 사용해 속성을 캡슐화할 수 있습니다.
gettter
및 describe
메소드로 확인이 가능하도록 만들어줍니다.
// 과일의 특징을 모은 기본 클래스
class Fruit {
// private 속성들 (캡슐화)
private name: string;
private weight: number;
private color: string;
private taste: string;
constructor(name: string, weight: number, color: string, taste: string) {
this.name = name;
this.weight = weight;
this.color = color;
this.taste = taste;
}
// describe 메소드: 과일의 특징을 설명 (추상화)
describe(): string {
return `${this.name}는 ${this.weight}g 무게를 가지고 있으며, ${this.color} 색상이고, 맛은 ${this.taste}입니다.`;
}
// getter 메소드들: 속성을 외부에서 접근할 수 있게 함 (캡슐화)
getName(): string {
return this.name;
}
getWeight(): number {
return this.weight;
}
getColor(): string {
return this.color;
}
getTaste(): string {
return this.taste;
}
}
이제 Fruit
클래스를 상속받아 특정 과일 클래스를 정의해 보겠습니다.
// 사과 클래스 (상속)
class Apple extends Fruit {
// Apple 클래스의 생성자: 부모 클래스의 생성자를 호출 (상속 및 오버라이딩)
constructor(weight: number, color: string, taste: string) {
super('사과', weight, color, taste);
}
// describe 메소드: 부모 클래스의 메소드를 오버라이딩 가능 (다형성)
describe(): string {
return `이것은 ${super.getName()}입니다. ${super.describe()}`;
}
}
// 바나나 클래스 (상속)
class Banana extends Fruit {
// Banana 클래스의 생성자: 부모 클래스의 생성자를 호출 (상속 및 오버라이딩)
constructor(weight: number, color: string, taste: string) {
super('바나나', weight, color, taste);
}
// describe 메소드: 부모 클래스의 메소드를 오버라이딩 가능 (다형성)
describe(): string {
return `이것은 맛있는 ${super.getName()}입니다. ${super.describe()}`;
}
}
다형성을 활용해 동일한 describe
메소드를 각 과일에 대해 사용할 수 있습니다.
const apple = new Apple(150, '빨간색', '달콤함');
const banana = new Banana(120, '노란색', '달콤함');
// 각각의 describe 메소드를 호출 (다형성)
console.log(apple.describe()); // 출력: 이것은 맛있는 사과입니다. 사과는 150g 무게를 가지고 있으며, 빨간색 색상이고, 맛은 달콤함입니다.
console.log(banana.describe()); // 출력: 이것은 바나나입니다. 바나나는 120g 무게를 가지고 있으며, 노란색 색상이고, 맛은 달콤함입니다.
OOP는 데이터 자체가 흩어져 있어서 과정을 그리는 시퀀스 다이어그램 같은 건 안맞고, 어떤 클래스가 어떤 관계를 정의하는지 나타내는 클래스 다이어그램을 사용해야합니다.
이러한 그림을 draw.io 같은 다이어그램 툴을 사용해 정의하면 구조를 한 눈에 파악할 수 있어 매우 유용할 겁니다.
프로토타입은 JavaScript에서 객체의 특성을 다른 객체에 상속하는 방식입니다. 모든 객체는 다른 객체를 원형(프로토타입)으로 삼아 자신을 정의할 수 있습니다. JavaScript는 프로토타입 기반 언어로, 객체 간의 상속을 프로토타입 체인(prototype chain)을 통해 구현합니다.
.
)을 형성합니다. 이를 통해 객체는 자신에게 직접 정의된 속성이나 메소드뿐만 아니라 상위 프로토타입을 불러올 수 있습니다.// class 사용 예제
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
// 새로운 Person 객체 생성
const alice = new Person('Alice');
alice.greet(); // "Hello, my name is Alice"
위 예제에서는 Person
이라는 클래스를 통해 새로운 객체를 만들고, Person.prototype
에 메소드를 정의해 모든 Person
객체가 이를 공유하게 했습니다.
// 생성자 함수 예제
function Person(name, age) {
this.name = name;
this.age = age;
}
// 프로토타입에 메소드 추가
Person.prototype.greet = function () {
console.log(`Hello, my name is ${this.name}`);
};
const alice = new Person('Alice', 30);
alice.greet(); // "Hello, my name is Alice"
extends
키워드를 사용해 상속을 구현할 수 있으며, super
키워드를 사용해 부모 클래스의 메소드를 호출할 수 있습니다.객체 지향 프로그래밍(OOP)은 소프트웨어 설계 방법론 중 하나로, 현실 세계의 개념을 객체라는 단위로 모델링해 프로그래밍하는 기법입니다. OOP의 주요 특징은 네 가지로 요약할 수 있습니다.
첫째, 추상화(Abstraction)는 복잡한 시스템을 단순화해 중요한 부분만을 노출하는 개념입니다. 이를 통해 복잡한 내부 구현을 숨기고, 사용자에게 필요한 기능만을 제공해 이해와 사용을 쉽게 합니다.
둘째, 캡슐화(Encapsulation)는 객체의 데이터와 메소드를 하나의 단위로 묶고, 외부에서 접근할 수 없도록 보호하는 개념입니다. 이를 통해 데이터 무결성을 유지하고, 객체 간의 상호작용을 제한해 프로그램의 안정성을 높입니다.
셋째, 상속(Inheritance)은 하나의 클래스가 다른 클래스의 속성과 메소드를 물려받아 재사용하는 기능입니다. 이를 통해 코드의 중복을 줄이고, 기존 코드의 수정 없이 기능을 확장할 수 있습니다.
마지막으로, 다형성(Polymorphism)은 동일한 인터페이스를 통해 서로 다른 구현을 사용할 수 있는 능력입니다. 이는 같은 이름의 메소드가 다른 객체에서 다르게 동작할 수 있게 해 유연하고 확장 가능한 코드를 작성할 수 있게 합니다.
이 네 가지 특성을 통해 OOP는 코드의 재사용성, 확장성, 유지보수성을 높이며, 복잡한 소프트웨어 시스템을 보다 효과적으로 관리할 수 있게 합니다.
AI로 뽑아봤습니다.
여러 가지 기능과 다양한 모듈이 서로 상호작용하는 대규모 애플리케이션에서 특히 OOP가 필요합니다. 이런 시스템에서는 코드의 유지보수, 확장, 재사용이 중요한데, OOP가 이러한 요구사항을 충족시키기 위해 매우 유용합니다.
엔터프라이즈 애플리케이션(Enterprise Applications):
웹 애플리케이션(Web Applications):
게임 개발(Game Development):
분산 시스템(Distributed Systems):
모바일 애플리케이션(Mobile Applications):