본문 바로가기
Learn to Code

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

by CEOSEO 2021. 4. 7.
728x90
반응형

프로그램(program)이란 무엇일까?

...라는 질문에 답하는 방식은 여러가지가 있을 수 있다. 그 이유는 프로그램을 바라보는 관점(perspective) 또는 패러다임(paradigm)이 여러가지이기 때문이다. 그중에서도 가장 전통적인 패러다임에 따르면 프로그램이란 '명령어 또는 함수의 목록'이 된다. 이 전통적인 관점은 명령형 프로그래밍(imperative programming)이라고 부르며, 이러한 패러다임을 따르는 언어들은 절차적 언어라고 불린다. (참고: 링크) 대표적으론 C언어가 있다.

 

 

 

객체 지향 프로그래밍(Object-Oriented Programming)

 

 

하지만 시간이 지나고 기술이 발전하면서, 프로그램을 바라보는 새로운 시각들이 생겨나기 시작했다. 객체 지향 프로그래밍도 그러한 패러다임들 중 하나이다. 객체 지향 프로그래밍(Object-Oriented Programming, OOP)은 객체(object)라는 개념에 기반한 프로그래밍 패러다임이다. 명령형 프로그래밍의 절차지향적 관점과는 다르게, 객체 지향 프로그래밍은 프로그램을 '객체(object)의 집합'으로 보는 패러다임을 말한다. 대표적으로 Java, C++, 그리고 C#이 객체 지향 언어로 분류되며, 자바스크립트 또한 객체 지향적으로 코드 작성이 가능하다.

 

여기서 말하는 객체(object)란 두 종류의 정보를 담고 있는 집합체를 뜻한다. 첫번째 종류는 속성(attributes, properties)이라 불리는 상태(state)를 나타내는 데이터이고 두번째 종류는 동작(behavior)을 나타내는 메소드(method)라 불리는 코드들을 의미한다. (출처) 즉, 객체란 상태 데이터와 동작을 하나의 논리적인 단위로 묶은 복합적인 자료구라고 할 수 있다.

 

 

 

 

객체 지향 프로그래밍의 4가지 핵심 개념

객체 지향 프로그래밍을 더욱 자세히 이해하기 위해선, 이것의 4가지 핵심 개념을 알고있어야 한다. 캡슐화(encapsulation), 추상화(abstraction), 상속(inheritance), 그리고 다형성(polymorphism)이 객체 지향 프로그래밍의 4가지 핵심 개념이다.

 

 

 

 

(1) 캡슐화(Encapsulation)란?

캡슐화는 객체의 상태(state)를 나타내는 속성과, 그 속성들을 참조하고 조작할 수 있는 동작인 메소드를 하나로 묶는 것을 뜻한다. 바로 객체 지향 프로그래밍의 기본적인 객체 구성 형태를 묘사하는 단어인 것이다. 속성과 메소드를 한 곳에 캡슐처럼 묶기 때문에, 이 개념에는 '은닉(hiding)'의 개념까지 포함되어 있다. 객체의 특정 속성이나 메소드를 감출 목적으로 캡슐화를 사용할 수도 있기 때문이다 (예: 클로저). 이를 통해 디테일한 구현은 숨기지만, 동시에 동작은 노출시키는 것이 가능해진다.

 

 

 

(2) 추상화(Abstration)란?

이미지를 클릭하면 출처 사이트로 이동한다. 객체 지향 프로그래밍의 4가지 원칙에 대해 상세히 설명한 글이다(영어).

추상화란, 한 물체(또는 객체)가 가진 여러 속성들 중에서 사용자가 필요한 속성만 간추려내어 표현하는 것을 뜻한다. 예를 들어, 사람에게는 다양한 속성이 있다. 성별, 나이, 눈색깔, 키, 몸무게, 전공, 거주지역, 국적, 사용언어 등등 아주 많은 속성들이 있다. 우리는 프로그램을 만들 때, 이 모든 속성들을 가져오지 않는다. 우리에게 필요한 것들만 골라서 간추린다. 바로 이 간추려 내어 표현하는 것을 추상화라고 하는 것이다.

 

위 그림을 보며 이해해보도록 하자. 그림의 왼쪽 편에 있는 사람 모양 아이콘과 가방 모양 아이콘은 현실 세계의 인간과 직업을 뜻한다. 가운데 박스의 Person과 Job은 현실세계의 인간과 직업이 가진 여러 속성들 중에서, 우리가 지금 만들려는 프로그램에 필요한 속성들만 골라놓은 작업을 진행한 결과인 클래스이다. 즉, 추상화가 진행된 결과이다. 그리고 오른편의 동그라미가 나타내는 Viktor, John, Roger와 Developer, Tennis player는 추상화 작업이 끝난 클래스를 기반으로 생성한 인스턴스들이다. (출처: 링크)

 

앞서 설명한 캡슐화가 데이터의 은닉에 포커스가 맞추어져 있다면, 추상화 같은 경우 클래스를 사용할 때 필요하지 않은 부분은 굳이 노출시키지 않는 것이 초점이 맞추어져 있다고 할 수 있다. 즉, 인터페이스의 단순화를 추구한다고도 표현할 수 있는 것이다.

 

 

 

(3) 상속(Inheritance)이란?

상속은 어떤 객체의 프로퍼티 또는 메소드를 다른 객체가 상속받아 그대로 사용할 수 있는 것을 말한다. 즉, 부모 클래스(base class)의 특징을 자식 클래스(derived class)가 물려받는 특성을 뜻하는 것이다. 예를 들어, '마법사'라는 직업을 게임에 추가한다고 생각해보자. 마법사 클래스를 처음부터 다시 만드는 것 보다, '초보자'라는 기존의 클래스에서 기본틀을 가져온 뒤 ( =상속한 뒤 ) 마법사 고유의 속성과 메소드를 추가하면 더욱 간편한 작업이 가능해질 것이다. 즉, 객체 지향 프로그래밍에선 상속의 특성이 있기 때문에 코드의 재사용성을 높일 수 있다.

 

 

(4) 다형성(Polymorphism)이란?

 

다형성이란 객체의 프로퍼티 또는 메소드를 다양한(poly) 형태(morph)로 변형시켜 사용할 수 있는 것을 말한다. 다른 말로 하자면, 다형성은 우리가 동일한 인터페이스 상에서 다른 종류의 다양한 객체들을 사용할 수 있도록 해준다. 예를 들어, 위 예시 그림과 같이 모든 동물들은 다른 소리를 낸다. 이렇듯 다른 소리를 내는 동물들을 동물이라는 동일한 클래스에서 만들어진 인스턴스라고 생각해보자. 그렇다면 말하는 행위를 speak()라는 하나의 메소드로 표현할 수 있을 것이다. 이 동물 인스턴스들은 모두 동일한 speak()라는 메소드 인터페이스 상에서 작동하지만, 나오는 결과물인 소리는 모두가 다를 것이다. (출처: 링크) 만약 이와 같은 다형성이 존재하지 않는다면, 우리는 반복적으로 speak() 기능을 각각의 동물들에게 넣어주는 반복적인 행위를 지속해야 했을 것이다.

 

 

<다향성 예시: 서브클래스>

2021.04.09 - [Learn to Code] - [JS] 클래스(Class), 인스턴스(Instance) 그리고 서브클래스 만들기(Subclassing)

 

 

객체(Object)의 현실 세계 예시

 

객체 지향 프로그래밍은 인간이 세상을 보는 관점과 굉장히 닮아있다. 그렇기 때문에, 현실 세상에 존재하는 무언가를 코드로 묘사할 때 조금더 쉽게 접근할 수 있다.

 

예시로, 위 사진과 같은 토끼를 자바스크립트 객체로 만들어보자. 객체 지향 프로그래밍 패러다임을 따르는 우리는, 이 토끼를 묘사하기 위해 우선 두 가지 측면에서 토끼를 분석하게 된다. 첫번째는, 토끼의 속성(attributes 또는 properties)이다. 여기에 해당되는 걸로는 '귀가 길다', '귀엽다', '복슬복슬하다', '하얀색이다', '똘망똘망한 눈을 가졌다' 등이 있을 수 있다. 모두 토끼의 모습을 설명해준다. 영어 문법으로 비유하자면, 토끼를 묘사할 때 사용할 수 있는 여러 형용사들을 생각해보라. (cute, pretty, fluffy 등등)

 

객체 지향 프로그래밍 패러다임을 따르는 우리가 할 수 있는 두번째 포인트는, 토끼가 할 수 있는 행동들을 정리하는 것이다. 여기에 포함할 수 있는 것은 '당근을 먹는다', '뛰어다닌다', '응아를 한다' 등이 있을 수 있다. 

 

위에 명시한 토끼의 특성과 행동은 다음과 같이 정리할 수 있을 것이다:

 

<토끼>

- Properties:

  • 귀: 길다
  • 외모: 귀엽다
  • 털: 복슬복슬하다
  • 색깔: 하얀색

- Methods:

  • 당근을 먹는다
  • 뛴다

이걸 기반으로 토끼라는 객체를 자바스크립트로 표현하면 아래와 같을 것이다.

 

 

const bunny = {
  // 프로퍼티
  ear: 'long',
  appearance: 'cute',
  hair: 'fluffy',
  color: 'white',
  
  // 메소드
  eatCarrots: function(numOfCarrots) {
    let poo = 1;
    poo = poo * numOfCarrots;
    return poo;
  },
  run: function(fondness) {
    let distance = 1;
    distance = -(distance * fondness)
    return distance;
  }
}

 

 

 

 

 

 

 

 

728x90
반응형

댓글