객체 지향 프로그래밍

잡초·2023년 3월 15일

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

객체 지향 프로그래밍이라는 패러다임이 등장하기 전, 절차 지향 프로그래밍이 있었다.
명령어, 또는 함수를 절차적으로 생각하는 명령형 프로그래밍. 이것을 절차적 언어라고 불렀다.

초기의 C, 포트란 같은 언어들은 객체 지향의 개념이 없는 절차적 언어였다.

그러나, 객체 지향 프로그래밍이라는 패러다임이 등장하면서, 단순히 별개의 변수와 함수로 순차적으로 작동하는 것을 넘어, 데이터의 접근과, 데이터의 처리 과정에 대한 모형을 만들어 내는 방식을 고안해냈다.

따라서, 데이터와 기능이 별개로 취급되지 않고, 한 번에 묶여서 처리할 수 있게 되었다.

여기서 말하는 객체란, 두 데이터를 담고 있는 집합체를 뜻한다.

즉, 객채란 상태 데이터와 동작을 하나의 논리적인 단위로 묶은 복합적인 자료구조라고 할 수 있다.

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

객체지향 프로그래밍을 더욱 자세히 이해하기 위해선, 4가지 개념을 알고있어야 한다.
캡슐화(Encapsulation), 추상화(Abstraction), 상속(Inheritance), 그리고 다형성(Polymorphism)

캡슐화(Encapsulation)

캡슐화는 외부에서 앞서 말했던 데이터(속성)와 기능(메서드)을 따로 정의하는 것이 아닌, 하나의 객체 안에 넣어서 묶는 것이다. 데이터(속성)와 기능(메서드)들이 느슨하게 결합되는 것이다.

느슨한 결합(Loose coupling)은 객체지향 설계에서 또 다른 중요한 개념으로, 각 모듈이 서로 독립적으로 존재하며, 변경이 일어나더라도 다른 모듈에 영향을 미치지 않도록 설계하는 것을 말한다. 이를 통해 유지보수성을 높이고, 코드의 재사용성을 높일 수 있다.

따라서, 캡슐화는 객체 내부의 상태를 보호하고, 해당 객체에서 제공하는 메서드를 통해서만 상태를 변경할 수 있도록 하는 것이다. 이는 다른 객체가 해당 객체의 상태를 직접 변경하지 못하도록 막음으로써 느슨한 결합을 유지할 수 있게 한다. 즉, 객체 간의 의존성을 최소화하여 느슨한 결합을 유지하면서도 객체 내부의 상태와 동작을 보호하는 것이다.

캡슐화라는 개념은 "은닉화"의 특징도 포함하고 있는데, 은닉화는 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것이다. 따라서, 디테일한 구현이나 데이터는 숨기고, 객체 외부에서 필요한 동작(메서드)만 노출시켜야 한다. 은닉화의 특징을 살려서 코드를 작성하면 객체 내 메서드의 구현만 수정하고, 노출된 메서드를 사용하는 코드 흐름은 바뀌지 않도록 만들 수 있다.

추상화(Abstraction)

추상화는 내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만든다는 개념이다.
예를 들어, 자동차라는 객체를 추상화한다면, 자동차의 색상, 모델명, 제조사 등의 구체적인 정보는 무시하고, 자동차가 가지는 주행능력, 속도, 연비 등과 같은 중요한 특성만을 강조하여 표현하는 것이다.

또한, 추상화는 객체의 내부 구현과 외부 동작을 분리함으로써 객체의 내부 구조를 변경하더라도 외부 인터페이스는 변하지 않도록 보장하는 장점도 가지고 있다.

추상화는 캡슐화와 비교해서 종종 헷갈려 하는 개념 중 하나다.

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

상속(Inheritance)

상속은 어떤 객체의 속성 또는 메소드를 다른 객체가 상속받아 그대로 사용할 수 있는 것을 말한다.
즉, 부모 클래스(base class)의 특징을 자식 클래스(derived class)가 물려받는 것이다.

예를 들어, 사람(Human)이라는 클래스가 있다고 가정해 보자. 사람은 기본적으로 이름과 성별, 나이와 같은 속성, 그리고 먹다, 자다 등과 같은 메서드가 있다고 볼 수 있다.

추가적으로 학생(Student)이라는 클래스를 작성한다고 생각해 보자. 그런데 이때 앞서 구현했던 사람(Human) 클래스의 속성과 메서드를 다시 구현한다면 비효율적일 것이다. 학생의 본질은 결국 사람이므로, 상속을 이용하여 학생(Student) 클래스는 사람(Human) 클래스를 상속받을 수 있다. 학생은 추가적으로 학습 내용, 공부하다 와 같은 속성/메서드를 추가한다.

개개체 지향 프로그래밍에선 상속의 특성이 있기 때문에 코드의 재사용성을 높일 수 있다.

다형성(Polymorphism)

Polymorphism이라는 단어의 poly는 "많은", 그리고 morph는 "형태"라는 뜻을 가지고 있다. 즉, "다양한 형태"를 가질 수 있다는 말이 된다.

"말하다"라는 동작의 본질은 "입으로 소리를 내다"를 의미한다. 그러나, 각기 다른 동물들이 "말할 때" 제각각의 소리를 내는 것처럼, 객체 역시 똑같은 메서드라 하더라도, 다른 방식으로 구현될 수 있다.

이 경우에는, TextBox, Select, Checkbox의 공통의 부모인 HTML Element라는 클래스에 render라는 메서드를 만들고 상속을 받게 만들 수 있다. 그런데 다형성의 핵심은 이 같은 이름의 render라는 메서드가 조금씩 다르게 작동한다는 데 있다.

만일 언어 자체에서 다형성을 제공하지 않는다면, 부모 클래스에 종류별로 분기를 시켜서 하나하나 다르게 만들어야 할 것이다.

또는 각각의 자식 클래스에 별도의 각기 다른 render 함수를 만들 수도 있겠지만, 엘리먼트라는 클래스의 본질상 "화면에 뿌린다"(render)는 개념은 부모가 갖고 있는 것이 합리적이다.

정리

  • 캡슐화는 코드가 복잡하지 않게 만들고, 재사용성을 높인다.
  • 추상화는 마찬가지로 코드가 복잡하지 않게 만들고, 단순화된 사용으로 변화에 대한 영향을 최소화한다.
  • 상속 역시 불필요한 코드를 줄여 재사용성을 높인다.
  • 다형성으로 인해 동일한 메서드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해진다.
profile
개발자가 되고싶은 잡초

0개의 댓글