객체 지향 프로그래밍(OOP) / Prototype / Class

지영·2021년 12월 24일
1

JavaScript

목록 보기
16/37
post-thumbnail
post-custom-banner

19. 프로토타입

객체 지향 프로그래밍(OOP)

  • 객체 지향 프로그래밍은 컴퓨터 프로그램을 여러개의 독립된 단위, 즉 객체들의 모임으로 파악하고자 하는 것이다.
  • 각각의 객체는 메시지를 주고 받고, 데이터를 처리할 수 있다.
  • 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하도록 하고, 소프트웨어 개발과 보수를 간편하게 하며, 직관적인 코드 분석을 가능하게 하는 장점을 갖는다.

  • 객체 지향 프로그래밍은 실제 세계에 기반한 모델을 만들기 위해 추상화를 사용하는 프로그래밍 패러다임이다.
  • 객체 지향 프로그래밍은 관계성 있는 객체들의 집합이라는 관점으로 접근하는 소프트웨어 디자인으로 볼 수 있다.
  • 각 객체는 별도의 역할이나 책임을 갖는 작은 독립적인 기계로 볼 수 있다.
  • 객체 지향 프로그래밍은 modularity(모듈화), polymorphism(다형성), encapsulation(캡슐화)를 포함하여 이전에 정립된 패러다임들부터 여러가지 테크닉들을 사용한다.

💡 다형성 (polymorphism)

: 프로그램 언어의 다형성(polymorphism)은 그 프로그래밍 언어의 자료형 체계의 성질을 나타내는 것으로, 프로그램 언어의 각 요소들(상수, 변수, 식, 오브젝트, 함수, 메소드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다. 반댓말은 단형성(monomorphism)으로, 프로그램 언어의 각 요소가 한가지 형태만 가지는 성질을 가리킨다.

-> 다형성 체계를 가진 언어에서는, StringValue와 같은 범용 메소드 이름을 정의하여 형태에 따라 각각 적절한 변환 방식을 정의해둠으로써 객체의 종류와 상관없는 추상도가 높은 변환 형식을 구현할 수 있다.

/* 단형성 체계 */
//숫자를 문자열로 바꾸는 경우
string = StringFromNumber(number);
//날짜를 문자열로 바꾸는 경우
string = StringFromDate(date);

/* 다형성 체계 */
//숫자를 문자열로 바꾸는 경우
string = number.StringValue();
//날짜를 문자열로 바꾸는 경우
string = date.StringValue();

객체 지향 프로그래밍(OOP)의 목적

  1. 객체 지향 프로그래밍은 실제 세계에 기반한 모델을 만들기 위해 추상화를 사용하는 프로그래밍 패러다임이다.
  2. 프로그램을 관계성 있는 객체들의 집합으로 파악한다.
  3. 객체는 별도의 역할이나 책임을 갖는 독립적인 기계로 볼 수 있다.
  4. 소프트웨어 개발과 유지보수를 쉽게 해주고 가독성에도 도움을 준다.

💡 응집력과 결합력

  • 소프트웨어 공학에서의 응집력은 하나의 모듈이 해당 기능을 수행하기 위한 책임과 역할로 뭉쳐있는 정도를 의미한다.
  • 결합력은 하나의 모듈이 다른 모듈과 얼마나 강력히 연결되어 있는지, 얼마나 의존적인지의 정도를 의미한다.

  • 객체 지향 프로그래밍(OOP)은 하나의 문제 해결을 위해 데이터를 모아 놓은 객체(클래스)를 활용한 프로그래밍을 지향하기 때문에 응집력이 강화할 수 있다.
  • 각 객체(클래스간)의 독립적인 디자인으로 결합력을 약하게할 수 있다.

객체 지향 프로그래밍(OOP)의 기본 구성 요소

  • Class
    객체 즉, 인스턴스를 찍어내는 공장
  • Instance
    • Class 즉, 공장에서 찍어내는 결과물
    • 상위 class의 속성도 가지고 있고 각각 개별적인 특성과 메소드를 가지고 있다.
  • Property & Method
    객체(인스턴스)의 상태 데이터(속성)를 프로퍼티, 동작(기능 수행)을 메서드 라고 부른다.

객체 지향 프로그래밍(OOP)의 특성

  • 캡슐화 (encapsulation)
    • 데이터 구조와 데이터를 다루는 방법들을 결합
    • 객체가 맡은 역할을 수행하기 위한 목적을 한 곳에 모으는 것
    • 외부에서의 내부 데이터 접근을 막을 수 있도록 은닉화
  • 상속 (inheritance)
    • 상위 개념의 속성을 하위 개념이 물려받는 것
    • 공통적인 기능을 하위 개념에 상속한다.
      (ex) 차의 기능을 여러 종류의 차에게 상속
  • 추상화 (abstraction)
    • 컴퓨터 프로그래밍에서의 추상화란 복잡한 소프트웨어 시스템을 효율적으로 설계하고 구현할 수 있는 방법.
    • 추상화는 뒷편 시스템의 기술적 복잡함을 단순한 API 뒤에 숨긴다.
    • 공통의 속성이나 기능을 묶어 이름을 붙이는 것.
      예를 들어, 컴퓨터가 어떻게 동작하고, 어떻게 만들어졌는지 알지 못해도 컴퓨터를 사용할 수 있다.
  • 다형성 (polymorphism)
    • 요소들(상수, 변수, 식, 오브젝트, 함수, 메소드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질
    • 부모 클래스에서 물려받은 함수를 자식 클래스 내에서 오버라이딩(상속 관계에 있는 부모 클래스에서 이미 정의된 메소드를 자식 클래스에서 같은 시그니쳐를 갖는 메소드로 다시 정의)하여 사용하는 것.
    • 서로 다른 클래스의 인스턴스(객체)가 같은 메시지를 받았을 때 각자의 방식으로 동작하는 능력

javascript에서 객체를 생성하는 법

  1. 생성자 함수
  2. 클래스
  3. Object.create()

1. 생성자 함수

  • 함수를 호출시 new 연산자를 사용하여 호출하면 생성자 함수로 실행되어 인스턴스를 생성한다.
  • new 연산자로 인해 생성자 함수의 this는 생성된 인스턴스를 바인딩(생성된 인스턴스를 가리킨다)한다.
function User(name, age) {
  this.name = name;
  this.age = age;

  this.sayName = function() {
    console.log(this.name);
  };
}

const user1 = new User("Lee", 20);

console.log(user1); // User {name: "Lee", age: 20, sayName: function (), constructor: Object}
user1.sayName();  // Lee
  • 만약 매우 많은 인스턴스를 생성해야 한다 가정한다면 메모리 누수가 발생한다. 이런 문제를 해결하기 위해 프로토 타입이라는 상속 방식을 사용한다.

부모와 자식이 있다고 가정했을 때, 부모는 자식을 위한 돈을 금고에 넣어두고 자식이 사용할 수 있도록 하였다.
이 예시에서의 금고프로토타입을 의미한다.
금고는 들고 다니는 것이 아닌 멀리 위치해 있는 보관용 상자이다.
따라서 금고(프로토타입)을 사용하여 메모리 누수를 줄일 수 있다.
부모는 조부모의, 조부모는 그 위의 부모의 돈을 금고에서 꺼내 체인처럼 연결하여 사용한다.
이것이 바로 프로토타입 체인이다. 프로토타입 체인은 최상위 객체(전역 객체)까지 이어져있다.
전역객체의 프로토타입에도 원하는 값이 없다면 참조 에러가 발생한다.

✍️ Prototype

function User(name, age) {
  this.name = name;
  this.age = age;
}

User.prototype.sayName = function() {
  console.log(this.name);
};

const user1 = new User("Lee", 20);

console.log(user1); // User {name: "Lee", age: 20, sayName: function (), constructor: Object}
user1.sayName(); // Lee

prototype vs _ _proto__

관점의 차이이다.
부모 입장에서 금고는 자식에게 금고이다.
자식 입장에서 부모의 금고는 부모에게서 받은 금고이다.

prototype__proto__를 나누는 이유는 시간이 흘러 자식 또한 자식을 낳아 상속을 시켜줘야 하기 위해 상속 받은 prototype과 상속 해주는 prototype의 구분이 필요하기 때문이다.

  • prototype
    상속을 시켜 줄 무언가
  • __proto__
    상속을 받는 무언가

Class (클래스)

자바스크립트는 클래스 기반 객체지향 프로그래밍 언어가 아닌 프로토타입 기반의 객체지향 프로그래밍 언어이다.
자바스크립트의 class는 기존 프로토타입 기반 패턴의 syntactic sugar(문법적 설탕)이라 볼 수 있다.


💡 클래스 사용

  1. class키워드 사용
  2. constructor생성자 메소드를 클래스 안에서 정의하여 해당 클래스로 인스턴스(객체)를 생성시 초기화할 값들을 정의한다.
  3. extends 키워드를 사용하여 클래스간 상속이 가능하다.
  4. super 키워드를 사용하여 부모 클래스의 constructor 생성자 메서드를 호출하거나 부모 클래스의 프로퍼티를 참조할 수 있다.

✍️ Class

class Parent {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sayName() {
    console.log(this.name);
  }
}

const parent = new Parent("Chulsu", 40);

console.log(parent); // User {name: "Chulsu", age: 40, sayName: function (), constructor: Object}
parent.sayName(); // Chulsu

class Children extends Parent {
  constructor(name, age, gender) {
    super(name, age);
    this.gender = gender;
  }
}

const child = new Children("Gildong", 2, "male");

console.log(child); // Children {name: "Gildong", age: 2, gender: "male", constructor: Object}
child.sayName(); // Gildong

Object.create()

prototype을 설정하기 위한 모던한 방법이 있다.
바로 Object.create 메소드를 사용해서 객체를 생성하는 방법이다.

💡 Prototype을 설정하기 위한 모던한 방법 -> Object.create()

  • Object.create(prototype)

    • Object.create 메서드의 인자로 Object.create 메서드가 호출되어 생성될 객체의 __proto__가 될 Prototype을 입력한다.
  • Object.getPrototypeOf(obj)

    • Object.getPrototypeOf메서드의 인자로 입력된 객체의 prototype을 리턴한다.
  • Object.setPrototypeOf(obj, prototype)

    • Object.setPrototypeOf 메서드의 첫번째 인자로 입력한 객체의 프로토 타입을 다른 객체 또는 null 로 설정할 수 있다.
    • Object.setPrototypeOf 메서드의 첫번째 인자로 입력한 객체에 두번째 인자를 prototype으로 추가해준다.

✍️ Object.create()

function Iphone() {
  this.applePay = true;
}

const proto = {
  canIUseApplePay: function() {
    console.log(this.applePay);
  }
};

const iphone = new Iphone();
Object.setPrototypeOf(iphone, proto);
iphone.canIUseApplePay(); // true

function IphoneInKorea() {
  this.applePay = false;
}
IphoneInKorea.prototype = Object.create(proto);

const iphoneInKorea = new IphoneInKorea();
iphoneInKorea.canIUseApplePay(); // false
profile
천천히 운영되는 개발 블로그
post-custom-banner

0개의 댓글