[javascript] 객체 지향 프로그래밍(Object Oriented Programming)

Hyebin·2021년 4월 10일
0

Javascript

목록 보기
21/27
post-thumbnail

프로그래밍 언어의 유형

절차적 언어, 객체 지향 언어, 함수형 언어, 논리형 언어 등이 있다.

절차적 언어(procedural Language)

는 말 그대로 절차를 순서대로 작성해 나가는 언어로 C, 포트 등 초기 프로그래밍 언어의 특징이다.

  • 장점
    복잡도가 지나치지 않고, 컴퓨터 처리구조와 유사해 실행속도가 빠르다.
  • 단점
    유지보수가 어렵고, 정해진 순서대로 입력이 않되면 결과 도출이 어렵다.

객체 지향 언어(Object-oriented Language)

데이터 접근, 데이터 처리와 절차를 하나로 묶어 객체 단위로 관리하는 언어이다.
그래서 데이터와 기능을 한번에 묶어서 처리할 수 있게 되었다. 현대의 언어들은 대부분 객체 지향적 특징을 갖는다. (Java, C++, C# 등)

  • 장점
    유지 보수 및 업그레이드가 쉽고, 코드 재활용이 가능하다. 대형 프로젝트에 적하다.
  • 단점
    처리 속도가 상대적으로 느리다. 설계에 많은 시간이 필요하다.

자바스크립트는 엄밀히 말하면 객체 지향 언어는 아니지만 객체 지향 패턴으로 작성할 수 있다.

C++, Java 등은 클래스를 이용하여 객체를 생성하는 클래스 기반 객체 지향 언어지만 자바스크립트는 클래스가 아닌 프로토타입을 상속하는 프로토타입 기반으로 작성할 수 있다.
자바스크립트에서는 객체를 생성한 후에도 프로퍼티와 메서드를 동적으로 추가하거나 삭제 할 수 있다는게 다른 객체 지향언어와 다른 점이다.

OOP란?

객체지향 프로그래밍의 약자(Object Oriented Programming)이며, 컴퓨터 프로그래밍 패러다임 중 하나로, 프로그램을 여러개의 '객체'로 나눠 객체들 간의 상호작용을 통해 로직을 짜는 방법이다.
객체는 한번 만들고 나면, 메모리상에서 반환되기 전까지 객체 내의 모든 것이 유지된다.

클래스와 인스턴스

클래스(class)

객체를 생성하기 위한 청사진이다. 집단에 공통적으로 속하는 속성과 기능을 변수와 메서드로 가지고 있다.

위 그림처럼 자동차에는 색상, 가격, 속력 등과 같은 고유의 속성이 존재하고, 후진, 전진, 멈춤과 같이 자동차의 기능이 메서드로 존재한다.

인스턴스(instance)

사실 인스턴스는 객체이다. 클래스를 통해 만들어진 객체를 부르기 위한 명칭으로 인스턴스라한다.
클래스에 정의한 행위를 수행할 수 있으며, 자신만의 고유 속성도 가질 수 있다.
인스턴스가 실제 프로그램에서 사용되는 데이터라 볼 수 있다.

생성자(constructor) 함수

생성자는 new 연산자와 함께 사용하여 객체를 생성하는 함수이다. 생성자를 사용하면 이름이 같은 메서드와 프로퍼티를 가진 객체를 효율적으로 여러 개 생성할 수 있다.
클래스는 객체를 만들기 위한 생성자 함수(constructor)를 포함한다.

OOP 특성

  • Encapsulation(캡슐화)
  • Inheritance(상속)
  • Abstraction(추상화)
  • Polymorphism(다형성)

1) 캡슐화

  • 데이터와 기능을 하나의 단위로 묶기 위해 속성과 기능(메서드)을 하나의 객체(캡슐) 안에 넣는다.
  • 캡슐화로 은닉(hiding)이 가능해진다.
    내부 데이터나 내부 동작이 외부에서 직접 접근되지 않고 함수를 통해 접근할 수 있도록 해주는 것이다.
  • 캡슐화의 장점
    데이터의 형태가 바뀔 때 메서드의 구현만 수정하고, 노출된 메서드를 사용하는 코드 흐름은 바뀌지 않도록 할 수 있다.

캡슐화는 클로저 모듈패턴을 사용해서 할 수 있다. counter의 value값이 바깥으로 노출되지 않는 형태로 만들어 줄 수 있다.

function makeCounter() {
  let value = 0
  return {
    increase: function() {
      value++
    },
    decrease: function() {
      value--
    },
    getValue: function() {
      return value;
    }
  }
}

counter1에 makeCounter() 함수를 할당해주면 키 값으로 함수를 갖는 객체를 갖게된다.
직접 value에 접근하지 않고, increase(), decrease(), getValue()함수를 통해 value에 접근할 수 있다. 그래서 counter1.value를 찍더라도 value값이 노출되지 않는다.

반면에 class 키워드를 사용한 캡슐화는 가능은 하지만 JavaScript 특성 상, 인스턴스에 묶인 모든 속성에 직접 접근이 가능하기 때문에 value값이 완전히 은닉되지 않는다.

class Counter {
  constructor() {
    this.value = 0;
  }

  increase() {
    this.value++;
  }

  decrease() {
    this.value--;
  }

  getValue() {
    return this.value;
  }
}

new 연산자로 Counter의 생성자 함수를 부르면 counter2에는 value를 키로 갖는 객체가 할당된다.
그렇기 때문에 getValue()로 value 값을 가져 올 수도 있지만, counter2.value로 직접 조회하더라도 value값을 가져올 수 있다.

2) 추상화

  • 중요한 정보만을 표현하는 것으로, 공통의 속성이나 기능을 묶어 이름 붙이는 것이다.
    인터페이스를 노출시키고 내부 구현은 신경쓰지 않는다.

실제 우리가 사용하는 폰 내부에는 칩, 카메라, 마이크 등 여러 부품으로 내부 구현이 되어 있지만 실제로 상용할 때는 이런 부품들을 생각하지 않고, 화면을 터치하여 기능들을 작동시킬 수 있는 것처럼 인터페이스(interface)를 단순화 할 수 있다.

캡슐화와 추상화의 차이는?

캡슐화는 코드나 데이터 은닉에 주요점을 둔다면, 추상화는 클래스를 사용하는 사람이 필요하지 않은 메서드 등을 노출시키지 않고, 기능 단순한 이름으로 정의하는 것에 주요점을 둔다.

인터페이스? 클래스 정의 시, 메서드와 속성만을 정의한것이다. 이것이 추상화의 본질!

3) 상속

  • 부모 클래스의 속성과 기능을 자식 클래스가 물려받아 사용할 수 있는 것을 말한다. 즉, 기본 클래스(base class)의 특징을 파생 클래스(derive class)가 상속받는다.

mini(자식클래스)의 본질은 Car(부모클래스)이고, mini가 출시일을 따로 갖듯이 자식클래스는 물려받는 속성 기능 외에 속성과 기능을 따로 가질 수도 있다.

4) 다형성

하나의 메서드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것을 의미한다.
동일한 메소드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해진다.

class Animal {
	speak() {
    	성대를 이용한다. 
    }
}

class Human extends Animal {
	speak() {
    	super.speak()
      	// 복잡한 어휘력
    }
}

class Dog extends Animal {
	speak() {
    	super.speak() 
        // 단순한 어휘력
    }
}

동물들을 제 각기 다른 소리를 내는것 처럼 객체 역시 똑같은 메서드라 하더라도 다른 방식으로 구현될 수 있다.

다형성을 제공하지 않는 다면, 부모 클래스에 종류별로 분리해서 하나씩 다 다르게 만들어줘야하는 번거로운 일이 생긴다.

OOP의 장점

  • 코드 재사용
    클래스를 가져와 쓸 수 있고, 상속을 통해 확장해서 사용할 수 있다. 클래스를 통해 동일한 객체를 만들 수 있다.
  • 유지보수가 쉬워진다.
    수정할 부분이 클래스 내부의 변수나 메서드로 있기 때문에 해당 부분만 수정해줄 수 있다.

0개의 댓글