객체 지향 프로그래밍이란 객체들의 유기적인 협력과 결합으로 파악하고자 하는 컴퓨터 프로그래밍의 패러다임을 의미합니다.
🙎♂️ : 마치 자동차를 만든다고 했을 때, 수 많은 부품들의 결합과 연결로 하나의 완전한 자동차가 만들어지는 것과 같다고 할 수 있습니다.
🥪🥪 핵심 🥪🥪
객체 지향적으로 소프트웨어를 설계한다는 말의 의미는 어떤 프로그램의 일부분에 해당하는 작은 부품, 즉 객체를 먼저 만들고 이렇게 만들어진 여러 객체들을 조립해서 하나의 완성된 프로그램을 만드는 프로그래밍 방법론을 뜻합니다.
자바스크립트에서 객체란 키(key)와 값(value) 으로 구성된 프로퍼티(property)와 메서드의 집합입니다.
아래의 예시를 보면 name,age 라는 것이 키(key) chan,25 라는 것이 값(value) 입니다.
또한 객체 안에서 함수 선언문으로 정의한 것을 메서드 라고 부릅니다.
그리고 이것들을 전부 프로퍼티 라고 합니다.
ES6 부터는 함수 선언문으로 선언한 함수만 메서드 라고 부르기로 약속했습니다.
const User = {name : chan, age : 25, sayHello: () => console.log('hello')}
이와 같이 객체는 데이터를 의미하는 프로퍼티(property)와 데이터를 참조하고 조작할 수 있는 동작(behavior)을 의미하는 메소드(method)로 구성된 집합입니다.
객체 지향 프로그래밍의 가장 큰 이점 중에 하나는 바로 객체 지향적 설계를 통해서 프로그램을 보다 유연하고 변경이 용이하게 만들 수 있다는 점입니다. 마치 컴퓨터 부품을 갈아 끼울 때, 해당하는 부품만 쉽게 교체하고 나머지 부품들을 건드리지 않아도 되는 것처럼 소프트웨어를 설계할 때 객체 지향적 원리를 잘 적용해 둔 프로그램은 각각의 객체들이 각자의 독립적인 역할을 가지기 때문에 변경하고 싶은 부분의 객체만 코드를 변경할수 있기 때문에 코드의 변경을 최소화하고 유지보수를 하는 데 유리합니다.
객체 지향 프로그래밍은 코드의 재사용을 통해 반복적인 코드를 최소화하고, 코드를 최대한 간결하게 표현할 수 있습니다. 또한 객체 지향 프로그래밍은 실제 우리가 보고 경험하는 세계를 최대한 프로그램 설계에 반영하기 위한 지속적인 노력을 통해 발전해왔기 때문에, 보다 인간 친화적이고 직관적인 코드를 작성하기에 용이합니다.
생성하고자 하는 객체를 정확한 이해하고 넓게 생각해야하기에 설계단계부터 많은 시간이 소모 됩니다.
객체 지향은 절차 지향보다 실행 속도가 느려집니다.
이유는 모든 것을 객체로 생각하기 때문에 추가적인 메모리와 연산에 대한 비용이 들어가게 됩니다.
객체 지향 프로그래밍의 4가지 특징은 각각 추상화, 상속, 다형성, 캡슐화입니다.
모두 이러한 객체 지향적 설계의 이점들을 가장 잘 살릴 수 있는 방향으로 발전되어 왔다고 할 수 있습니다.
추상화(Abstraction)는 객체 지향 프로그래밍(OOP)에서 중요한 개념 중 하나로, 복잡한 현실 세계를 모델링할 때 필요한 세부 사항을 감추고 핵심적인 특성과 동작만을 강조하는 프로그래밍 원칙입니다.
🙎♂️ : 예를 들어, 자동차를 추상화하면 "자동차는 주행하고 멈출 수 있다"라는 핵심 아이디어에 집중하고, 엔진이나 변속기와 같은 복잡한 부분을 신경 쓰지 않는 것입니다.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks`);
}
}
const myDog = new Dog('Buddy');
myDog.speak(); // "Buddy barks"
위 코드를 보면 Animal(동물) 을 추상화 한 개념으로, Dog(강아지) 가 짖는 것을 강조하는 예시 입니다.
상속은 부모 클래스의 특성과 동작을 자식 클래스가 상속받는 개념입니다. 상속을 통해 코드의 재사용성을 높일 수 있고, 계층 구조를 만들어 관리하기 쉽게 합니다.
🙎♂️ : 아빠와 엄마의 특징을 아이가 물려받는 것처럼, 상속은 부모 객체의 특징과 기능을 자식 객체가 물려받는 개념입니다. 예를 들어, 자전거 클래스가 부모이고, 일반 자전거와 전기 자전거가 자식일 때, 자전거의 기능을 자식 자전거가 상속받아 사용할 수 있습니다.
class Shape {
constructor(x, y) {
this.x = x;
this.y = y;
}
area() {
console.log('Shape area calculation');
}
}
class Circle extends Shape {
constructor(x, y, radius) {
super(x, y);
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
}
const myCircle = new Circle(0, 0, 5);
console.log(myCircle.area()); // 78.53981633974483
이 코드를 보면 Shape 클래스는 도형을 나타내며 Circle 클래스는 Shape 클래스를 상속합니다. Circle 클래스는 area 메서드를 재정의하여 원의 넓이를 계산하도록 변경합니다.
다형성은 여러 클래스가 동일한 메서드를 가지고 있지만 각 클래스마다 다른 동작을 하는 개념입니다. 다형성을 통해 코드의 유연성을 높이고 다양한 객체를 처리할 수 있습니다.
🙎♂️ : 여러 가지 모양이나 기능을 가진 것을 한 번에 처리하는 능력입니다. 예를 들어, 모든 동물이 "소리를 내다"라는 명령을 받을 수 있지만, 각 동물은 다른 소리를 낼 것입니다. 다형성을 사용하면 여러 동물들을 모두 묶어서 같은 명령을 내릴 수 있습니다.
class Animal {
speak() {
console.log('Animal makes a sound');
}
}
class Dog extends Animal {
speak() {
console.log('Dog barks');
}
}
class Cat extends Animal {
speak() {
console.log('Cat meows');
}
}
function makeAnimalSpeak(animal) {
animal.speak();
}
const myDog = new Dog();
const myCat = new Cat();
makeAnimalSpeak(myDog); // "Dog barks"
makeAnimalSpeak(myCat); // "Cat meows"
위에 코드를 보면 Animal 이라는 클래스에서 speak 라는 메서드를 정의하고 있지만
상속을 통해 각자 기능이 다른 메서드로 동작하게 만들 수 있습니다.
캡슐화는 객체의 상태와 행동을 하나로 묶어 외부에서 직접 접근하지 못하게 하는 개념입니다.
캡슐화를 통해 객체 내부의 상태를 보호하고 유지보수성을 높일 수 있습니다.
🙎♂️ : 마치 선반에 옷을 넣어두고 문을 닫는 것처럼, 중요한 것들을 감추는 개념입니다. 예를 들어, 비밀번호를 알지 않으면 열 수 없는 잠금된 상자처럼, 객체의 일부를 외부로부터 숨길 수 있습니다. 이로써 안전하고 실수를 방지할 수 있습니다.
class BankAccount {
constructor(accountNumber) {
this._accountNumber = accountNumber; // 언더스코어(_)를 통한 은닉
this._balance = 0;
}
deposit(amount) {
if (amount > 0) {
this._balance += amount;
}
}
withdraw(amount) {
if (amount > 0 && amount <= this._balance) {
this._balance -= amount;
}
}
getBalance() {
return this._balance;
}
}
const myAccount = new BankAccount('123456');
myAccount.deposit(1000);
myAccount.withdraw(500);
console.log(myAccount.getBalance()); // 500
위 코드를 보면 _accountNumber와 _balance 속성을 언더스코어(_)
를 사용하여 은닉되어 있으며, 외부에서 직접 접근할 수 없습니다.
대신에 deposit, withdraw, getBalance 메서드를 사용하여 상호작용할 수 있습니다.
이 외에도 protected, private 와 같은 코드로 정보를 보호 할 수 있습니다.
이러한 개념들은 객체 지향 프로그래밍에서 중요하며, 프로그램을 더 이해하기 쉽고 효과적으로 만들어줍니다.