객체지향 프로그래밍(Object-Oriented Programming; OOP)의 주요 특징으로는 캡슐화, 추상화, 상속, 다형성이 있다.
정보은닉을 추가하여 5가지라고 보는 경우도 있으니, 캡슐화와 정보은닉의 차이점에 유의하며 주요 특징들을 알아보자.
1. 캡슐화(Encapsulation)
변수와 함수를 캡슐처럼 하나의 단위로 묶는 것을 의미한다. 즉 데이터의 번들링(Bundling)이다.
이처럼 객체의 속성(data fields)과 행위(메서드)를 하나로 묶기도 하고, 실제 구현 내용 일부를 외부로부터 감춰 은닉한다는 특징이 있어 캡슐화라고 한다.
대개 프로그래밍 언어에서 이 번들링은 클래스를 통해 구현되고, 해당 클래스의 인스턴스(객체) 생성을 통해 클래스 안에 포함된 멤버 변수와 메소드에 쉽게 접근할 수 있다. 클래스는 객체 지향 프로그래밍을 지원하는 거의 대부분의 언어가 제공하는 제1요소이다.
1-1. 정보 은닉(Informaion hiding)
프로그램의 세부 구현이 외부로 드러나지 않도록 특정 모듈 내부로 감추는 것이다.
내부의 구현은 감추고 모듈 내에서의 응집도를 높이며, 외부로의 노출을 최소화해 모듈간의 결합도를 떨어트려 유연함과 유지보수성을 높이는 개념이다.
많은 객체지향 언어에서 사용되는 클래스를 기준으로 보자.
클래스 외부에서는 바깥으로 노출된 특정 메서드에만 접근이 가능하며 클래스 내부에서 어떤 식으로 처리가 이루어지는지는 알지 못하도록 설계된다. 일반적으로 private, public, protected 세 종류의 접근 제한이 사용된다.
- private: 클래스의 내부에서만 사용되며 외부로 노출되지 않는 것
- public: 클래스의 외부에서 사용 가능하도록 노출시키는 것
- protected: 다른 클래스에게는 노출되지 않지만, 상속받은 자식 클래스에게는 노출되는 것
2. 추상화(Abstraction)
실제 세상이나 복잡한 프로그램을 만들기 위한 객체를 필요한 정보만을 중심으로 간소화하는 것을 말한다. 프로그래밍 언어에서는 객체들의 공통적인 속성과 기능을 중심으로 추상화한다.
3. 상속(Inheritance)
자식 클래스가 부모 클래스의 특성과 기능을 그대로 물려받는 것을 말한다. 기능의 일부분을 변경해야 할 경우 자식이 부모 클래스에게서 상속받은 그 기능만을 수정해서 다시 정의하게 되는데, 이러한 작업을 '오버라이딩(Overriding)'이라고 한다.
상속은 캡슐화를 유지하면서도 코드의 불필요한 중복을 줄이며 클래스의 재사용이 용이하도록 해 준다.
4. 다형성(Polymorphism)
어떤 변수나 함수가 상황에 따라 다른 의미로 해석될 수 있는 것을 말한다.
동일한 이름의 여러 오퍼레이션(메소드)을 다른 사양으로 정의 가능한 특징을 다형성이라고 한다.
상속받은 메소드를 수정해 사용하는 오버라이딩과 동일한 메소드명이되 받는 인자의 자료형이나 매개변수가 다른 오버로딩도 다형성의 특징을 보여주는 예에 해당한다.
조금 더 깊게 들어가면 다음 4가지로 분류할 수 있다.
- 매개변수 다형성 : 타입을 매개변수로 받아 새로운 타입을 되돌려주는 기능
- 템플릿 : C++에서 사용하는 개념. 타입 매개변수를 입력한 타입으로 치환한 코드를 생성. 타입 말고 변수도 입력 가능.
- 제네릭 : Java와 C# 등에 도입된 개념. 지정한 타입 매개변수에 해당하는 타입만 사용하겠다고 약속하는 방식. - 서브타입 다형성 : 기초 클래스나 어떤 인터페이스를 구현하는 상위 클래스를 생성하고, 해당 클래스 상속받는 하위 클래스들을 만들어 상위 클래스 포인터, 참조변수 등이 하위 클래스 객체를 참조하게 하는 것.
이 때 각각의 하위 클래스는 상위 클래스의 메소드 덮어쓰는 메소드 오버라이딩 수행. 상위 클래스의 참조변수가 어떤 하위 클래스의 객체를 참조하냐에 따라 호출되는 메소드가 달라짐.
Java, C++, C#, Python, Ruby 등 객체 지향 언어들은 기본적으로 지원하는 개념. - 임시 다형성
- 함수 오버로딩 : 동일한 이름의 함수를 매개변수에 따라 다른 기능으로 동작하도록 할 수 있다. 함수 오버로딩을 너무 많이 사용하면 전체적인 코드의 유지보수가 어려워지므로, 템플릿 또는 제네릭으로 대체하는 것이 일반적이다.
- 연산자 오버로딩 : 연산자를 오버로딩해서 기본 연산자가 해당 클래스에 맞는 역할을 수행하게 하는 것이 가능하다. Java에서는 연산자의 오버로딩이 불가능하다. - 강제 다형성
- 묵시적 형 변환 : 'double a = 30;' 처럼 double형에 int형을 넣으면 더 크기가 큰 double 자료형으로 형 변환이 일어나는데, 이를 자료형 승급이라고 한다. 이러한 자료형 승급과 C++의 변환 생성자에 의한 형 변환이 묵시적 변환에 해당된다. 이를 막으려면 생성자 앞에 explicit 키워드를 추가해야 한다.
- 명시적 형 변환 : 'double a = (double)30;'은 위의 묵시적 형 변환과 동일한 결과를 내지만, int가 double 형으로 변환됨을 명시적으로 보여주는 형 변환이다.
참고 : 객체 지향 프로그래밍 나무위키
'[C_C++]이론 공부 > 이론+STL' 카테고리의 다른 글
[C++ STL] set 사용법 위주 공부 (0) | 2021.06.29 |
---|---|
[C++ STL] vector(벡터) 공부 (0) | 2021.06.14 |
[C++] 클래스(class) 기본 (0) | 2021.06.01 |
[C++] 데이터 타입(자료형) (0) | 2021.05.20 |
[C++] 메모리 영역 (메모리 구조), 정적할당과 동적할당 (0) | 2021.05.20 |