
객체 지향 프로그래밍(OOP : Object-Oriendted Programming)은 모든 것을 절차적으로 생각하는 절차적 프로그래밍과 다르게 데이터와 기능을 한 곳에 묶어서 처리하는 방식을 말한다.
속성과 메서드가 하나의 객체라는 개념에 포함되며, 이는 자바스크립트 내장 타입인 object 와는 다르게 class 라는 이름으로 부른다.
쉽게 풀어서 말하자면, 하나의 모델이 되는 청사진을 만들고, 그 청사진을 바탕으로 한 객체를 만드는 프로그래밍 패턴이다.
여기서 청사진은 class 를 뜻하며, 청사진을 바탕으로 한 객체는 instance 를 뜻한다.
class 라고 부르는 데이터 모델의 청사진을 사용해 코드를 작성한다.생성자 함수를 사용하며 생성자 함수는 일반적인 다른 함수와 구분하기 위해 대문자로 시작하고 일반명사로 만든다.
// ES5
function Car(brand, name, color) {
// 인스턴스가 만들어질 때 실행되는 코드
}
// ES6
class Car {
constructor(brand, name, color) {
// 인스턴스가 만들어질 때 실행되는 코드
}
}
클래스의 새로운 객체를 생성하려면 new 키워드와 생성자 함수를 사용하여 인스턴스를 만든다.
// new 키워드를 사용하여 클래스의 새로운 인스턴스 생성
let avante = new Car('Hyundai', 'avante', 'blakc');
avante 인스턴스는 Car 클래스의 고유한 속성과 메서드를 가지게 된다.
속성을 정의하기 위해선 this 키워드를 사용한다. 여기서 this 는 인스턴스 객체를 뜻한다.
// ES5
function Car(brand, name, color) {
this.brand = brand;
this.name = name;
this.color = color
}
// ES6
class Car {
constructor(brand, name, color) {
this.brand = brand;
this.name = name;
this.color = color;
}
}
메서드를 정의하기 위해 ES5 문법에선 prototype 키워드를 사용하고 ES6 문법에선 생성자 함수와 함께 class 키워드 안쪽에 묶어서 정의한다.
// ES5
function Car(brand, name, color) { ... }
Car.prototype.refuel = function() {
// 연료 공급을 구현하는 코드
console.log(`${this.name}이/가 연료를 넣는 중입니다.`);
}
// ES6
class Car {
constructor(brand, name, color) { ... }
refuel () {
// 연료 공급을 구현하는 코드
console.log(`${this.name}이/가 연료를 넣는 중입니다.`);
}
}
🎯 여기서 잠깐!
prototype: 모델의 청사진을 만들 때 쓰는 원형 객체(original form)이다.
this: 함수가 실행될 때, 해당 scope 마다 생성되는 고유한 실행 context(execution context)이다.new키워드로 인스턴스를 생성했을 땐, 해당 인스턴스가 바로this의 값이 된다.
은닉화는 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만든다. 세부적인 구현은 숨기고, 객체 외부에서 필요한 동작(method)만 노출시킨다.
느슨한 결합은 코드 실행 순서에 따라 절차적으로 코드를 작성하는 것이 아니라, 코드가 상징하는 실제 모습과 닮게 코드를 모아 결합하는 것을 의미한다. 즉 클래스간의 의존성이 줄어들게 된다.
마우스 구동을 위한 코드 작성을 예시로 들자면, 스위치가 눌러지고, 전기 신호가 생겨서, 전선을 타고 흐르고... 등과 같은 전 과정을 이곳저곳에 나누어 작성하는 것이 아니라, 마우스의 상태를 속성으로 정하고 클릭/이동을 메서드로 정해서 코드만 보고도 인스턴스 객체의 기능을 상ㅅ아할 수 있게 작성하는 것이 느슿나 결합을 추구하는 코드 작성법이다.
🎯 코드가 복작하지 않게 만들고, 재사용성을 높일 수 있다.
전화기를 예로 들자면, 전화기 내부엔 동작을 위한 복잡한 회로가 존재하지만, 사용자는 내부에 신경 쓸 필요 없이 단순하게 숫자 버튼과 수화기를 사용하여 통화를 할 수 있다.
이러한 추상화를 통해 인터페이스가 단순해지고, 많은 기능이 노출되지 않은 덕분에 예기치 못한 사용상의 변화가 일어나지 않도록 만들 수 있다.
class 정의 시, 메서드와 속성만 정의한 것을 interface 라고 부른다.
🎯 캡슐화와 마찬가지로 코드가 복잡하지 않게 만들고, 단순화된 사용으로 변화에 대한 영향을 최소화한다.
정확히 말하자면 "기본 클래스의(base class)의 특징을 파생 클래스(derived class)가 상속받는다" 라고 표현할 수 있다.
사람을 클래스로 본다면, 기본적으로 성별/나이/키/몸무게 등의 속성이 있고, 먹다/자다 등의 메서드가 있을것이다.
추가적으로 학생이라는 클래스를 작성할 때 앞서 구현한 사람 클래스와 비슷한 속성들이 존재한다. 이 때 상속을 이용하여 학생 클래스는 사람 클래스를 상속받고 추가 속성(학교/학년/반...) 메서드(등교하다/공부하다...)를 작성할 수 있다.
🎯 불필요한 코드를 줄여 재사용성을 높인다.
동물을 예로 들자면, 동물 클래스의 인스턴스인 개/고양이/닭은 "짖다" 라는 똑같은 메서드를 지니고 있지만, 인스턴스마다 짖는 방법은 다를 것이다.(멍멍/야옹/꼬끼오)
🎯 동일한 메서드에 대해 if/else if 와 같은 조건문 대신 개겣의 특성에 맞게 다르게 작성하는 것이 가능하다.