포스트

[OOP] 객체 지향 프로그래밍이란?

Computer Science / OOP

객체 지향 프로그래밍(Object-Oriented Programming , OOP)에 대한 개념 정리와 기타 관련된 정보, 개념 정리

객체 지향 프로그래밍의 개념

객체 지향 프로그래밍(Object-Oriented Programming , OOP)이란, 컴퓨터 프로그램을 어떤 데이터를 입력받아 순서대로 처리하고 결과를 도출하는 명령어들의 목록으로 보는 시각에서 벗어나 여러 독립적인 부품들의 조합, 즉 객체들의 유기적인 협력과 결합으로 파악하고자 하는 컴퓨터 프로그래밍의 패러다임을 의미한다.

마치 자동차를 만든다고 했을 때, 수 많은 부품들의 걀합과 연결로 하나의 완전한 자동차가 만들어지는 것과 같다고 할 수 있다.

객체 지향적으로 소프트웨어를 설계한다는 말의 의미는 어떤 프로그램의 일부분에 해당하는 작은 부품, 즉 객체를 먼저 만들고 이렇게 만들어진 여러 객체들을 조립해서 하나의 완성된 프로그램을 만드는 프로그래밍 방법론을 뜻한다.

객체 지향 프로그래밍의 특징

객체(Object)란?

객체는 객체 지향 프로그래밍의 가장 기본적인 단위이자 시작점이라고 할 수 있다.

객체 지향 개념의 가장 기본적인 전제로는, 실제 세계는 객체들로 구성되어 있으며, 보여지는 모든 현상과 발생하는 모든 사건은 이러한 객체들 간의 상호작용을 통해 발생한다는 것에서 출발한다.

다시 돌아와서 객체란 무엇인가?

oop_3

주변에 존재하는 책상, 의자, 시계, 전등, 책 등 우리가 주변에서 흔히 볼 수 있는 모든 실재(實在)하는 대상을 객체 지향 프로그래밍 언어에서는 객체라고 부른다.

한 마디로, 객체는 우리가 보고 느끼고 인지할 수 있는 그 모든 것을 의미한다고 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Car {
  // 속성 정의
  company: string;
  model: string;
  color: string;
  wheels: number;
  isConvertible: boolean;

  // 기능 정의
  startEngine(): void {
    console.log("시동 걸기");
  }

  moveForward(): void {
    console.log("🚗 <- <- <- <- <- <- 🚗");
  }

  moveBackward(): void {
    console.log("🚗 -> -> -> -> -> -> 🚗");
  }
}

객체 지향 프로그래밍에서는 이와 같은 각각의 객체를 추상화시켜 속성(State)기능(Behavior)으로 분류한 후에 이것을 다시 각각 변수(Variable)함수(Function)로 정의하고 있다.

OOP의 장점

  • 유지보수의 우수성, 생산성 향상
    가장 큰 이점 중 하나는 객체 지향적 설계를 통해서 프로그램을 보다 유연하고 변경이 용이하게 만들 수 있다는 점이다.
    소프트웨어를 설계할 때 객체 지향적 원리를 잘 적용해 둔 프로그램은 각각의 부품들이 각자의 독립적인 역할을 가지기 때문에 코드의 변경을 최소화하고 유지보수 하는 데 유리하다.

    마치 컴퓨터 부품을 갈아 끼울 때, 해당하는 부품만 쉽게 교체하고 나머지 부품들을 건드리지 않아도 되는 것과 같다.

  • 재사용성
    코드의 재사용을 통해 반복적인 코드를 최소화하고, 코드를 최대한 간결하게 표현할 수 있다.
  • 자연적인 모델링
    객체 지향 프로그래밍은 실제 우리가 보고 경험하는 세계를 최대한 프로그램 설계에 반영하기 위한 지속적인 노력을 통해 발전해왔기 때문에, 보다 인간 친화적이고 직관적인 코드를 작성하기에 용이하다.

OOP의 단점

  • 개발 속도 저하
    객체가 처리하려는 것에 대한 정확한 이해가 필요하기에 설계 단계부터 많은 시간과 노력이 요구된다.
  • 처리 속도 저하
    객체 지향 언어는 대체적으로 처리 속도가 상대적으로 느리다.
  • 코딩 난이도 상승, 용량 문제
    다중 상속이 지원되는 C++같은 경우, 너무 복잡해져서 코딩의 난이도가 기하급수적으로 상승할 수 있다.
    객체가 많아지면서 용량이 커지는 문제가 발생할 수 있다.

OOP의 4가지 특징

oop_2 객체 지향 프로그래밍의 4가지 특징으로는 추상화, 상속, 다형성, 캡슐화가 있다.

추상화 (Abstraction)

추상이라는 용어의 사전적 의미를 보면 사물이나 표상을 어떤 성질, 공통성, 본질에 착안하여 그것을 추출하여 파악하는 것이라 정의하고 있다.

여기서 핵심이 되는 개념은 공통성과 본질을 모아 추출한다는 것이다.

oop_4 예를 들면, 서울의 지하철 노선도는 서울의 지리를 추상화시켜서 보여주는 대표적인 예라고 할 수 있다.

중요한 부분을 강조하기 위해 불필요한 세부 사항들은 제거하고 가장 본질적이고 공통적인 부분만을 추출하여 표현하는 것과 관련이 있다.

자세한 내용은 #객체 지향 프로그래밍의 특징 - 추상화 (Abstraction) 참고

상속 (Inheritance)

oop_5 상속이란 기존의 클래스를 재활용하여 새로운 클래스를 작성하는 문법 요소를 의미한다.

상속은 클래스 간의 공유될 수 있는 속성과 기능들을 상위 클래스로 추상화 시켜 해당 상위 클래스로부터 확장된 여러 개의 하위 클래스들이 모두 상위 클래스의 속성과 기능들을 간편하게 사용할 수 있도록 한다.

즉, 클래스들 간의 공유하는 속성과 기능들을 반복적으로 정의할 필요 없이 딱 한 번만 정의해두고 간편하게 재사용할 수 있어 반복적인 코드를 최소화하고 공유하는 속성과 기능에 간편하게 접근하여 사용할 수 있도록 한다.

자세한 내용은 #객체 지향 프로그래밍의 특징 - 상속 (Inheritance) 참고

다형성 (Polymorphism)

oop_6 다형성은 객체 지향 프로그래밍의 꽃이라고 할 수 있으며, 상황과 환경에 따라서 달라지는 성질을 의미한다.

다형성(多形性)이란, 한자 그대로 어떤 객체의 속성이나 기능이 상황에 따라 여러 형태를 가질 수 있는 성질을 의미한다.

위의 이미지처럼 상황에 따라 남자의 역할이 자식에게는 부모, 회사에서는 팀장, 동호회에서는 리더 등 상황과 환경에 따라 달라지는 것과 비슷하다고 할 수 있다.

즉, 어떤 객체의 속성이나 기능이 그 맥락에 따라 다른 역할을 수행할 수 있는 객체 지향의 특성을 의미한다.

대표적인 예로 메서드 오버라이딩(overriding)과 메서드 오버로딩(overloading)이 있다.

자세한 내용은 #객체 지향 프로그래밍의 특징 - 다형성 (Polymorphism) 참고

캡슐화 (Encapsulation)

oop_7

캡슐화란, 클래스 안에 서로 연관있는 속성과 기능들을 하나의 캡슐(Capsule)로 만들어 데이터를 외부로부터 보호하는 것을 말한다.

위의 그림처럼 서로 관련있는 데이터와 이를 처리할 수 있는 기능들을 한 곳에 모아 관리하는 것이다.

객체 지향 프로그래밍에서 이렇게 캡슐화를 하는 이유는 크게 두 가지이다.

  • 데이터 보호 (Data Protection)
    외부로부터 클래스에 정의된 속성과 기능들을 보호
  • 데이터 은닉 (Data Hiding)
    내부의 동작을 감추고 외부에는 필요한 부분만을 노출

자세한 내용은 #객체 지향 프로그래밍의 특징 - 캡슐화 (Encapsulation) 참고

클래스 기반 VS 프로토타입 기반

클래스 기반 언어

클래스 기반 언어1는 클래스로 객체의 자료 구조와 기능을 정의하고 생성자를 통해 인스턴스를 생성한다.

클래스는 앞서 설명했듯이, 속성과 행위를 정의한 것으로 객체 지향 프로그램의 기본적인 사용자 정의 데이터형(User Define Data Type)이라고 할 수 있다.

결국, 클래스는 객체 생성에 사용되는 패턴 혹은 청사진(Blueprint)일 뿐이며, new 연산자를 통한 인스턴스화 과정이 필요하다.

모든 인스턴스는 오직 클래스에서 정의된 범위 내에서만 작동하며, 런타임에 그 구조를 변경할 수 없다.

이러한 특성은 정확성, 안정성, 예측성 측면에서 클래스 기반 언어가 프로토타입 기반 언어보다 좀 더 나은 결과를 보장한다.

아래의 예제는 Java로 구현된 클래스로, Javaclass 키워드를 제공하고 이것으로 클래스를 정의한다. 생성자는 클래스명과 동일하며, 메소드로 구현된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Person {
  private String name;

  public Person(String name) {
    this.name = name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }

  public static void main(String[] args) {
    Person me = new Person("Han");

    String name = me.getName();
    System.out.printIn(name); // Han
  }
}

프로토타입 기반 언어

들어가기에 앞서,

대표적인 프로토타입 기반 언어인 JavaScript의 경우, ECMAScript6(ES6, ECMA6)2에서 새롭게 클래스가 도입되었다.

ES6의 Class는 기존 prototype 기반 객체 지향 프로그래밍보다 Class 기반 언어에 익숙한 프로그래머가 보다 빠르게 학습할 수 있는 단순하고 꺠끗한 새로운 문법을 제시하고 있다.

ES6의 Class가 새로운 객체 지향 모델을 제공하는 것이 아니며, Class도 사실 함수이고, 기존 prototype 기반 패턴의 Syntactic sugar3이다.

JavaScript는 멀티-패러다임 언어로 명령형(Imperative), 함수형(Functional), 프로토타입 기반(Prototype-Based) 객체 지향 언어이다.

비록, 다른 객체 지향 언어들과의 차이점에 대한 논쟁이 있지만, JavaScript는 강력한 객체 지향 프로그래밍 능력들을 지니고 있다.

간혹 클래스가 없어서 객체 지향이 아니라고 생각하는 사람들도 있으나(필자 본인도 해당) 프로토타입 기반의 객체 지향 언어이다.

JavaScript는 클래스 개념이 없고 별도의 객체 생성 방법이 존재한다.

  • 객체 리터럴
  • Object() 생성자 함수
  • 생성자 함수
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 객체 리터럴
var obj_1 = {};
obj_1.name = "Han";

// Object() 생성자 함수
var obj_2 = new Object();
obj_2.name = "Hyung";

// 생성자 함수
function F() {}
var obj_3 = new F();
obj_3.name = "Jin";

console.log(`${obj_1.name} ${obj_2.name}-${obj_3.name}`);
// Han Hyung-Jin

JavaScript는 이미 생성된 인스턴스의 자료 구조와 기능을 동적으로 변경할 수 있다는 특징이 있다.

객체 지향의 상속, 캡슐화(정보 은닉) 등의 개념은 프로토타입 체인과 클로저 등으로 구현할 수 있다.

클래스 기반 언어에 익숙한 프로그래머들은 이러한 프로토타입 기반의 특성으로 혼란을 느끼지만, JavaScript에서는 함수 객체로 많은 것을 할 수 있는데, 클래스, 생성자, 메소드도 모두 함수로 구현이 가능하다.

객체 지향 언어의 사용

사용하기에 적합한 경우

  • 많은 데이터를 다루는 프로그램
  • 규모가 큰 프로젝트를 다루는 경우

사용하기에 적합하지 않은 경우

  • 극도로 빠른 실행 속도가 필요한 분야
  • 저장 장치나 성능이 제한적인 기기4에서 돌아가는 프로그램을 만들 때
    • 임베디드와 같은 특정 분야라고 생각하면 쉽다.

객체 지향 언어의 종류

oop_8

  • Java
    객체 지향 언어의 대표적인 언어
  • Simula67 (시뮬라67)
    최초의 객체 지향 언어로 알려져 있음
  • Smalltalk (스몰토크)
    최초로 GUI를 제공하는 언어
  • Objective-C (오브젝티브-C)
    애플의 운영체제인 iOS에서 사용되는 언어
  • Visual Basic .NET (VB.NET, 비주얼 베이직 닷넷)
    비쥬얼 베이직(VB)의 발전된 객체 지향 언어
  • C++
    객체 지향성이 더해진 C 언어의 확장형
  • C#
    .NET 플랫폼에 의존도가 높은 프로그래밍 언어
  • Embarcadero Delphi (엠바카데로 델파이)
    오브젝트 파스칼 프로그래밍 언어로부터 파생된 언어인 Delphi를 이용
  • Python (파이썬)
    플랫폼 독립적이며, 인터프리터식, 객체 지형적, 동적 타이핑(Dynamically Typed) 대화형 언어
  • Perl (펄)
    인터프리터 방식의 프로그래밍 언어 혹은 그 인터프리터 소프트웨어
  • Ruby (루비)
    동적 객체 지향 스크립트 프로그래밍 언어이고, 순수 객체 지향 언어
  • ActionScript (액션스크립트)
    2000년 7월 ActionScript 1.0이 플래시 5에서 처음 소개
  • ASP (Active Server Page, 액티브 서버 페이지)
    마이크로소프트 사에서 동적으로 웹 페이지들을 생성하기 위해 개발한 서버 측 스크립트 엔진
  • Swift (스위프트)
    애플이 iOS 8과 OS X 프로그래밍을 위해 개발한 언어

객체 지향 언어가 인기를 얻은 이후에 기존의 프로그램이 언어들이 객체 지향의 요소를 추가하거나 확장하는 형태가 만들어지게 된다.

참고 사이트

코드스테이츠 - 객체 지향 프로그래밍의 4가지 특징ㅣ추상화, 상속, 다형성, 캡슐화

라다it는 정보프렌 - 객체지향언어란? [특징, 장점, 단점, 종류]

PoiemaWeb - 자바스크립트 객체지향 프로그래밍

강이의 개발블로그 - [Java] 상속 관계와 포함 관계

Sanghyuk’s Blog - 객체 지향의 장점과 단점


  1. Java, C++, C#, Python, PHP, Ruby, Object-C 등… ↩︎

  2. ECMAScript란, ECMA International이 ECMA-262 기술 규격에 따라 정의하고 있는 표준화된 스크립트 프로그래밍 언어를 말하며, 기존에 자바스크립트의 여러 문제점을 해결하고 개선한 ES6(ECMAScript 2015)이 2015년 여름에 발표 되었으며, ES6은 ECMAScript 2015라도고 불리고, 기존 여러 기능을 개선한 버전이다. ↩︎

  3. 문법적 기능은 그대로인데 그것을 읽는 사람이 직관적으로 쉽게 코드를 읽을 수 있게 만든다는 것이다. ↩︎

  4. 스마트 워치, 스마트 TV, 스마트 냉장고 등… ↩︎

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.