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

Hyo Kyun Lee·2021년 10월 22일
0

WebDevCurriculum

목록 보기
7/44

개요

Javscript의 객체지향프로그래밍에 대해 알아본다.

Checklist

객체지향 프로그래밍

  • 객체지향 프로그래밍은 무엇일까요?
    → OOP, Object Oriented Programming
    → 프로그램의 동작은 여러 객체들이 모여 이루어진다는 개념에서 출발한다.
    → 객체는 크게 두가지 특징인 속성(attribute)과 행동(Behavior)을 가지고있으며, 특정 속성을 가진 객체들의 행동이 맞물려 프로그램 동작이 이루어진다는 개념이다.
    ※ python에서 활용하는 객체개념과 동일한 개념이지만, class를 통한 구현(python)과 프로토타입기반의 객체프로그래밍(javscript)을 통한 구현이라는 점에서 다르다.

  • 프로토타입 기반의 객체지향 프로그래밍은 무엇일까요?
    → Python이 class 기반의 객체지향이라면, Javascript는 프로토타입 기반의 객체지향이다.
    → 객체를 재활용할 경우 대여의 개념인 class와는 다르게(객체가 서로 나뉘어져 있음), 항상 기존 객체(원형)을 참조한다는 개념이다.
    → 모든 변수, 함수, component 등은 prototype을 보유하고 있다는 특징을 가지고 있다(단, boolean과 같은 원시형태는 prototype이 존재하지 않는다).

  • 자바스크립트의 클래스는 이전의 프로토타입 기반의 객체지향 구현과 어떤 관계를 가지고 있나요?
    → class가 없던 Javascript는 객체를 생성할 때 별도의 내부 생성자없이 바로 객체를 생성하였고, 이에 따른 속성이나 행동 값들을 부여해주었다.
    → ES6이후 생긴 class에서는 constructor 생성자를 통해 정의해줄 수 있고, 외부 생성자인 new를 통해 class를 생성하거나 상속받을 수 있다.

javascript object
※ object를 통해 prototype이 정의됨

function Animal(type, name, sound) {
  this.type = type;
  this.name = name;
  this.sound = sound;
}

prototype

function Animal(type, name, sound) {
  this.type = type;
  this.name = name;
  this.sound = sound;
}

Animal.prototype.say = function() {
  console.log(this.sound);
};

javascript class

class Animal {
  constructor(type, name, sound) {
    this.type = type;
    this.name = name;
    this.sound = sound;
  }

※ OOP의 3대 요소 : 캡슐화/다형성/상속

  • 캡슐화(encapsulation), 정보은닉(informaton hiding)
    → private 속성을 바탕으로 객체간 정보공유를 통해 발생하는 버그나 데이터 임의변경, 의존성 등을 개선하기위해 고안된 개념이다.
    → 캡슐화 : 데이터 속성과 행동을 하나의 함수(prototype)에서 정의하며, 외부에서의 접근을 허용하지 않는 특성이다.
    → 정보은닉 : 캡슐화에서 확장되는 개념으로, 한 객체의 정보가 다른 객체와의 정보공유를 허용하지 않는 특성이다.

  • 다형성이란 무엇인가요? 다형성은 어떻게 코드 구조의 정리를 도와주나요?
    → 하나의 클래스가 다양한 형태와 동작방식을 가질 수 있다는 개념으로, 동일한 prototype임에도 실행결과가 다른 다양한 객체로써 활용할 수 있다는 의미이다.
    → 주로 상속을 통해 클래스를 확장해가는 것으로 이해하면 되며, 클래스의 속성이나 동작방식을 넓혀가는 것을 의미한다.

  • 상속이란 무엇인가요?
    → 쉽게 말하면 class 확장, 모든 class는 다른 class의 속성과 행동을 유지한채 종속적인 관계의 class를 생성할 수 있다.
    ※ 기본적으로 class나 prototype은 최상위 class인 부모 class와, 이를 확장하여 부모 class의 속성과 행동을 동일하게 사용할 수 있는 자식 class로 구분할 수 있다.
    → 상속의 핵심개념 : 추상화(abstraction), 속성 및 행동의 중복 제거

객체지향 프로그래밍과 코드 재활용

  • 상속의 한계
    → 객체는 기본적으로 독립적이어야 하며, application은 이러한 독립적인 객체들의 기능이 긴밀하게 모여 이루어진 문서이자 집합체이다.
    → 상속은 보통 기존의 class에서 속성과 기능을 추가할때 활용되는 개념으로, 추가기능이 많아진다면 코드 나 용량 측면에서 과부하가 이루어진다(클래스 폭발).
    → 이와 같이 부모 class(prototype)의 속성과 행동을 그대로 유지하여 확장받는 상속의 특성상, 이러한 객체지향 프로그래밍의 기조를 유지하기는 매우 힘들다.

  • OOP의 합성(Composition)이란 무엇인가요?
    → 이러한 상속의 단점을 보완하면서 코드 재사용을 가능하도록 해주는 기능이 합성(Composition)이다.
    → 상속의 경우 부모 class에 대한 외부 생성자를 생성한 후 별도의 접근이 필요하지만, 합성을 할 경우엔 부모/자식 class 상관없이 한 줄의 코드로 직접적인 접근이 가능해진다.

Inheritance

Card card = new Card;
value = card.NormalPolicy();

Composition

Card card = new Card(new VaxPolicy(0.1, new NormalPolicy());
  • 합성이 상속에 비해 가지는 장점은 무엇일까요?
    → 상속의 경우 컴파일 단계에서 관계가 고정되어 런타임 시점에서 class간 속성 및 관계를 변화시킬 수 없다.
    → 합성은 이러한 단점을 보완하여, 런타임 시점에서 class 관계를 변화시킬 수 있다.

  • protected property(private 속성의 전신)
    → 마치 보호커버와 같이, application의 세부내용들을 보호할 목적으로 객체로의 접근을 제한하는 것을 의미한다.
    → 내부인터페이스라고도 하며, 특정 인터페이스를(protected 속성을 생성한 프로토타입) 통해서만 접근할 수 있다.
    → ※ python class에서는 private 속성을 통해 구현하며, javascript에서는 protected 속성을 통해 구현한다.

참조개념

  • python "객체지향언어"와의 비교
    → 결론적으로는 python의 객체와 javascript의 객체는 서로 동일한 개념이다.
    → python에서 선언하는 문자들은 모두 객체이기 때문에, 모든 문자들은 고유의 속성과 행동을 가진다.
    → 다만 python에서는 객체속성을 property(프로퍼티), 객체행동을 method(메소드)라 부른다(※ Javascript에서의 객체속성은 state(상태), 객체행동은 behavior(행동).)

  • 다만, python은 class기반의 언어이다.
    → python에서 객체를 생성하는 방법은 class라는 틀을 통해 이루어지며, 하나의 class 내부에서 모든 property와 method를 정할 수 있다.

  • Javascript는 class 기반의 언어는 아니다.
    → 기존의 Javascript는 Prototype 기반의 프로그래밍으로, class가 존재하지 않았다.
    → python class와 javascript에서의 객체지향언어의 상속(Inheritance), 캡슐화(정보은닉) 등의 형태는 다르기 떄문에, 각 언어에 맞는 pattern 학습이 필요하다.
    → 최근 ES6 도입 이후에서야 javscript에서의 class 생성이 가능해졌다.

  • 프라이빗필드(#)
    → 최근 Javascript에 추가된 protected 속성을 강화한 프라이빗 필드이다.
    → protected 속성이 생성자(let prototype = new prototype)을 통해서도 접근이 가능하다면, private은 생성자를 통해서 접근이 불가능하다.

  • 반드시 프라이빗 필드를 정의한 prototype 내부에서, 객체로 접근하기위한 내부생성자(set)를 선언해줘야 접근이 가능하다.

javascript의 private 속성 예시

  • private 속성을 선언한다면 외부 생성자를 통한 접근은 불가능하다.
class SuperMarket {
  #product = 200;

  #CheckValue(value) {
    if (value < 0) throw new Error("물건가격을 다시 확인해주세요.");
    if (value > this.#producet) throw new Error("적정가격을 초과하였습니다.");
  }

}

let Market1 = new SuperMarket();

// 클래스 외부에서 private에 접근할 수 없음
Market1.#checkValue(150); // Error(*접근불가)
Market1.#product = 1000; // Error(*접근/수정불가)
class SuperMarket {

  #product = 200;

  //private 속성에 접근하기 위해선 별도의 내부 get/set 생성자 선언이 필요하다.
  get yourPrice() {
    return this.#waterAmount;
  }
	
  //private 속성에 접근하기 위해선 별도의 내부 get/set 생성자 선언이 필요하다.
  set yourPrice(value) {
    if (value < 0) throw new Error("가격은 0이하가 될 수 없습니다.");
    this.#waterAmount = value;
  }
}

let Market1 = new SuperMarket();

Market1.yourPrice() = 200;
alert(machine.#waterAmount); // Error (*접근불가)
  • 상속을 할 때의 장점과 단점?
    → 특징 : Javascript가 동적인 특성을 가지기 때문에, class에 전달되는 인자형태는 class/prototype 작동에 영향을 별로 주지 않는다(오류를 발생시키지 않는다).
    (※ C언어의 경우 인자형태가 달라지면 이에 따른 별도의 class 및 함수생성이 필요)
    → Javascript prototype을 재활용하여, 코드 재활용 및 중복 제거 관점에서 용이한 기능이다.
    → 단점 : 상속은 기본적으로 부모 class에 대한 명확한 이해가 필요하며, 객체간 독립성을 유지하기가 힘들어지기 때문에, 무분별한 상속은 피해야 한다.

정리

0. why

  • Application의 동작은 다양한 함수, component 등 객체의 집합을 통해 이루어진다.
  • 이러한 동작원리나 구조를 명확히 이해하기 위해 Javascript의 객체지향 프로그래밍을 반드시 숙지해야 한다.

1. what

  • 객체지향프로그래밍의 개념과 선언방법 등에 대해 파악한다.
  • class 개념과 비교하면서 어떤 차이점이 있는지 비교한다.

2. how

  • 객체지향프로그래밍의 지향점을 이해하고, 이를 실무에 어떠한 방향으로 적용할 것인지 고민해본다.

참조자료

javascript / python
https://velog.io/@suasue/JavaScript-%EA%B0%9D%EC%B2%B4-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EA%B3%BC-%EB%B9%84%EA%B5%90%ED%95%98%EB%A9%B0-%EB%B0%B0%EC%9A%B0%EA%B8%B0

Javascript protected / private
https://ko.javascript.info/private-protected-properties-methods

OOP의 3대요소
https://hyperline.tistory.com/11

캡슐화 / 정보은닉
https://photojin.tistory.com/93

다형성 / 상속
https://codevang.tistory.com/81

상속/합성
https://hue-dev.site/engineering/2021/05/20/%EC%83%81%EC%86%8D%EA%B3%BC-%ED%95%A9%EC%84%B1%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC.html

프로토타입(prototype)
https://poiemaweb.com/js-prototype

객체/프로토타입/class
https://learnjs.vlpt.us/basics/10-prototype-class.html

0개의 댓글