객체 지향 프로그래밍

yeon·2022년 9월 21일
0

FE

목록 보기
6/15

클래스와 인스턴스

Javascript는 원래 프로토타입을 기반으로 하지만, ES6 이후 클래스를 기반으로 한 객체 지향 프로그래밍이 가능해졌다.

  • ES5 작성 문법
function Car(brand, name, color){
	this.brand = brand;
    this.name = name;
    this.color = color;
}

Car.prototype.refuel = function(){
}

Car.prototype.drive = function(){
}
  • ES6 작성 문법
class Car {
	constructor(brand, name, color){
    	this.brand = brand;
    	this.name = name;
    	this.color = color;
      	refuel(){
        }
      	drive(){
        }
    }
}

클래스

  • 일종의 원형(original form)으로, 객체를 생성할 수 있는 아이디어나 청사진, 틀
  • 서로 연관있는 것들을 객체로 구성 → 속성과 메서드가 하나의 "객체"라는 개념에 포함됨
  • 클래스 이름은 보통 대문자로 시작하며 일반명사로 만듦
  • 생성자constructor 함수: 세부 사항(속성)이 들어감. 인스턴스가 만들어질 때 실행되는 코드
    • 생성자 함수를 작성하지 않으면 기본 생성자(default constructor)가 제공됨
    • 생성자 함수는 하나만 있을 수 있음
    • 부모 클래스가 있고, 자식 클래스가 생성자 함수를 작성하지 않으면 부모 생성자를 부름
  • super 부모 클래스의 함수를 호출할 때 사용
    • 생성자에서 super 키워드 하나만 사용되어야 함
    • this 키워드가 사용되기 전에 호출되어야 함

인스턴스

  • 클래스를 이용하여 만들어진 객체를 인스턴스 객체 instance object, 줄여서 인스턴스instance 라고 함
  • 인스턴스를 만들 때 new 키워드 사용
    → 즉시 생성자 함수가 실행되며, (변수에 클래스의 설계를 가진 새로운 객체) 인스턴스가 할당됨
    this는 인스턴스 객체를 의미(해당 인스턴스가 바로 this의 값이 됨)
  • 각각의 인스턴스는 클래스의 고유한 속성과 메서드(객체에 딸린 함수)를 가짐
  • 배열은 전부 Array의 인스턴스
    • 배열 메서드 (push, filter, forEach...) 등을 배울 때, 메서드들이 Array.prototype.메서드명
    • 모든 메서드들이 클래스의 원형 객체(prototype)에 정의되어 있기 때문
  • 인스턴스.__proto__ === 클래스.prototype
    • 인스턴스.__proto__.__proto__ === 상속받은 클래스의 부모 클래스.prototype
    • 인스턴스.__proto__.__proto__.__proto__ === Object.prototype

객체 지향 프로그래밍

객체 지향 프로그래밍은 절차 지향 프로그래밍과는 다르게 데이터와 기능을 한곳에 묶어서 처리한다. Java나 C+, C# 등 현대 언어 대부분은 객체 지향의 특징을 가지고 있다. 하지만 Javascript는 엄밀하게 객체 지향 언어는 아니지만, 객체 지향 패턴으로 작성이 가능하다.

객체 지향의 주요 개념(캡슐화, 추상화, 상속, 다형성)을 통해 재사용성을 높일 수 있다.

Encapsulation(캡슐화)

  • 데이터(속성)와 기능(메서드)를 하나의 객체 안에 넣어서 묶음
  • 느슨한 결합: 코드만 보고도 인스턴스 객체의 기능을 상상할 수 있도록, 코드가 상징하는 실제 모습과 닮게 코드를 모아서 결합
  • 은닉화: 내부 데이터나 내부 구현이 외부로 노출되지 않게 만듦
    • 절차적 코드는 데이터가 바뀌면 코드 흐름에 영향을 미치게 되어 유지 보수가 어렵지만, 은닉화해서 코드를 작성하면 객체 내 메서드 구현만 수정하고 노출된 메서드를 사용하는 코드 흐름은 바뀌지 않도록 할 수 있어 유지 보수에 유리함
    • Javascript는 private 키워드를 지원하는 브라우저가 적어 널리 쓰이지 않지만, 은닉화를 돕기 위해 클로저 모듈 패턴 사용 → ES2019부터 클래스, 인스턴스 형태로 만들 때 # 키워드가 도입됨
  • 코드가 복잡해지지 않음

Inheritance(상속)

  • 부모 클래스(기본 클래스base class) 특징을 자식 클래스(파생 클래스 derived class)가 물려받음
  • 불필요한 코드를 줄임

Abstraction(추상화)

  • 내부 구현은 복잡하지만, 실제로 노출되는 부분은 단순하게 만듦
  • interface의 단순화 (interface: 클래스 정의 시 메서드와 속성만 정의한 것)
    • Javascript에서는 interface 기능 존재하지 않음
    • 어떤 클래스가 외부 공개용으로 모듈처럼 작동하는 interface 사용 예) API
  • 캡슐화는 은닉에 중점을 두고, 추상화는 필요하지 않은 메서드 등을 노출시키지 않으면서 단순한 이름으로 정의하는 것에 중점을 둠
  • 코드가 복잡해지지 않고, 단순화된 사용으로 변화에 대한 영향을 최소화함

Polymorphism(다형성)

  • 같은 메서드라 하더라도, 다른 방식으로 구현될 수 있음
  • if/if else 조건문 대신, 객체의 특성에 맞게 달리 작성 가능함

프로토타입

Javascript는 프로토타입을 기반으로 만들어진 언어이다. 비슷한 object들이 있다면 이들의 비슷한 속성이나 메서드를 하나의 프로토타입으로 만들어서 이를 이용해 객체 지향을 구현한다.

class Animal {
	constructor(name, age){
    	this.name = name;
      	this.age = age;
    }
  	
  	eat(){
    	console.log(`${this.name}이 먹는다`)
    }
}

let dog = new Animal('choco', 5);

Animal.prototype.constructor === Animal // true
Animal.prototype === dog.__proto__; // true
Animal.prototype.eat === dog.eat; // true

배열 또한 Array 클래스의 인스턴스이다.

프로토타입 체인

Javascript에서 상속을 구현할 때 프로토타입 체인을 사용한다. 부모 클래스로부터 상속받은 자식 클래스는 부모 클래스의 속성과 메서드를 상속받아 사용할 수 있다. extendssuper 키워드를 통해 상속을 구현할 수 있다.

보통 클래스의 인스턴스는 new 키워드로 생성하지만, DOM에서는 new 대신 createElement를 사용한다.

Object (모든 클래스의 조상)EventTargetNodeElementHTMLElementHTMLDivElement

  • DOM을 이용해 생성한(document.createElement('div')) div 엘리먼트는 HTMLElement라는 클래스의 인스턴스이다.
  • div가 addEventListener 메서드를 사용할 수 있는 이유도 EventTarget을 상속하기 때문! (EventTarget의 프로토타입에 addEventListener 메서드가 있음)

0개의 댓글