객체 지향 프로그래밍
용어 정리
ex) Car
클래스: 그냥 ‘자동차’ 그 자체의 청사진. 세부사항이 들어있지 않다.
생성자: constructor 자동차의 세부사항이 들어있다. 설계도. 함수에 인자를 넣듯이 속성을 넣을 수 있다.
인스턴스: 설계도를 바탕으로 만들어낸 여러 자동차 제품. 자동차의 예시.
메서드: 시작, 후진, 전진, 멈춤, 주유, 주행과 같은 자동차의 기능
인스턴스를 만들 때는 new 키워드를 사용해야 한다.
new 키워드를 사용하면 생성자 함수(constructor)가 실행되어 설계도(class)에 따라 만들어진 제품(instance)이 할당된다.
작성 문법
// 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;
}
refuel() {
console.log(this.name + '에 연료를 충전했습니다.');
}
drive() {
console.log(this.name + '가 운전을 시작합니다.');
}
}
this는 인스턴스 객체를 의미한다. parameter로 넘어온 브랜드, 이름, 색상 등은 인스턴스 생성 시 지정하는 값이며, 위와 같이 this에 할당한다는 것은 만들어진 인스턴스에 해당 브랜드, 이름, 색상을 부여하겠다는 의미다. 메서드는 constructor와는 별개로 선언해준다.
객체 지향
프로그램이 별개의 변수와 함수를 통해 순차적으로 작동하는 것을 넘어, 데이터의 접근과 처리 과정에 대한 모형을 만들어 내는 방식.
데이터와 기능이 별개로 취급되지 않고, 한 번에 묶여서 처리된다.
캡슐화 Encapsulation
데이터와 기능을 한 데 묶는 것.
느슨한 결합: 코드만 보고도 인스턴스 객체의 속성과 기능을 상상할 수 있게 작성하는 것.
은닉화: 내부 데이터나 내부 구현이 외부로 노출되지 않도록 하는 것.
코드가 복잡하지 않도록. 코드의 재사용성을 높일 수 있도록.
추상화
내부 구현은 복잡하나, 노출되는 부분은 단순하게 만든다는 개념.
코드가 복잡하지 않도록. 단순화된 사용으로 변화에 대한 영향을 최소화할 수 있도록.
상속
부모 클래스의 특징을 자식 클래스가 물려받는 것.
자식 클래스로 가면 그 속성이 디테일해진다. (음료 ⇒ 커피, 교통수단 ⇒ 자동차, 사람 ⇒ 학생 등)
그래서 기본적인 속성은 부모에게서 상속 받고, 디테일한 속성이나 메서드를 자식 클래스에 추가한다.
코드의 재사용성을 높일 수 있도록.
다형성
부모로부터 똑같이 상속 받은 메서드라 해도, 자식의 형태에 따라 그 메서드가 사용되고 작동하는 방식이 다르다.
다형성이 없다면, 부모 클래스에 종류별로 분기를 시켜서 하나하나 다르게 만들어야 한다.
Object prototypes
우리가 const arr = [4, 2, 1]; 선언했을 때,
arr에 sort 라는 메서드를 추가해 준 적이 없는데 어떻게 쓸 수 있는 것인가?
const arr = [4, 2, 1];
와
const arr = new Array(4, 2, 1);
은 같다.
그럼 arr은 Array의 자식이 되고, Array.prototype이 가지고 있는 메서드를 사용할 수 있는 것이다.
Array.prototype.내가만든함수 = function(){}
‘내가만든함수’를 모든 Array에서 쓸 수 있다.
클래스 안에 쓰면 자식도 직접 갖고 있게 되고, 프로토타입으로 추가해주면 부모만 가진다.
프로토타입: 유전자
function 기계() {
this.q = ‘strike’;
this.w = ‘snowball’;
}
const nunu = new 기계();
콘솔에 기계.prototype 찍으면 { constructor: f }가 나옴
기계.prototype.constructor === 기계
기계.prototype === nunu.__proto__;
기계.prototype.q === nunu.q;
프로토타입 체인
자식을 계속 낳아서 대대손손 연결되어있는 관계
div.__proto__ // HTMLDivElement
div.__proto__.__proto__ // HTMLElement
div.__proto__.__proto__.__proto__ // Element
div.__proto__.__proto__.__proto__.__proto__ // Node
div.__proto__.__proto__.__proto__.__proto__.__proto__ // EventTarget
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__
// Object
div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__ // null
메서드를 사용할 때는 바로 위 부모부터 뒤진다. 최상위 조상이랑 바로 위 부모가 같은 메서드 갖고 있으면 부모 걸 사용한다.
.prototype
유전자
.proto
부모 유전자 체크
Object
모든 클래스의 조상
Object.proto ⇒ null
주의할 점
상속 받고자 하는 부모 ‘객체’를 자식의 프로토타입에 할당해줘야 함.
자식의 프로토타입에 부모의 ‘프로토타입’을 할당해주면,
자식의 프로퍼티를 수정할 경우 부모에게 영향을 미칠 수 있다.