객체 지향 프로그래밍에 대해 이해하기전 객체 지향 프로그래밍 OOP가 등장한 배경에 대해서 먼저 작성하도록 하겠습니다.
정의한 기능의 흐름에 따라 동작을 추가하며 프로그램을
완성하는 방식이다. 간단한 프로그램의 경우, 순차적 프로그래밍으로 코드를 작성하게 되면 흐름이 눈으로 보이기 때문에 직관적일 것입니다. 하지만 프로젝트의 사이즈가 큰 프로그램의 경우 중간에 지나왔던 클래스로 돌아가야한다면 goto와 같은 기능을 사용해야하는데 이는 동작이 직관적이지 못하게 되고 유일한 장점을 잃어버리는 것입니다.
그래서 등장한 것이 절차적, 구조적 프로그래밍입니다.
절차적 프로그래밍에서 절차는 함수를 의미합니다. 따라서 절차적 프로그래밍이란 반복되는 동작을 함수 및 프로시저 형태로 모듈화하여 사용하는 것을 의미합니다.
프로시저란 :
리턴값이 없는 함수를 말합니다. 예를 들어 데이터를 출력하는 용도로 사용하는 printf와 같은 함수를 프로시저라고 합니다. (엄밀히 따지면 printf도 리턴값이 있지만 본래 목적이 리턴과 무관하기에 프로시저에 가깝습니다.)
객체지향프로그래밍은 컴퓨터 프로그래밍 패러다임 중 하나로, 프로그래밍에서 필요한 데이터를 추상화 시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법입니다.
코드 재사용에 용이
: 남이 만든 클래스를 가져와서 이용할 수 있고 상속을 통해 확장해서 사용할 수 있습니다.
유지보수의 쉬움
: 절차 지향 프로그래밍에서는 코드를 수정해야 할 때 일일이 찾아 수정해야 하는 반면 객체 지향 프로그래밍에서는 수정해야 할 부분이 클래스 내부에 멤버 변수 혹은 메서드로 존재하기 때문에 해당 부분만 수정하면 됩니다.
대형 프로젝트에 적합
: 클래스 단위로 모듈화 시켜서 개발할 수 있으므로 대형 프로젝트처럼 여러 명, 여러 회사에서 프로젝트를 개발할 때 업무 분담하기 쉽습니다.
처리 속도가 상대적으로 느립니다.
객체가 많으면 용량이 커질 수 있습니다.
설계시 많은 시간과 노력이 필요합니다.
4가지를 알아보기전 클래스와 인스턴스(객체)에 관해 간단하게 설명하고 가겠습니다.
: 어떤 문제를 해결하기 위한 데이터를 만들기 위해 추상화를 거쳐 집단에 속하는 속성과 행위를 변수와 메서드로 정의한 것으로 객체를 만들기 위한 메타정보라고 볼 수 있습니다.
: 클래스에서 정의한 것을 토대로 실제 메모리에 할당된 것으로 실제 프로그래밍에서 사용되는 데이터입니다.
객체들이 공통적으로 필요로 하는 속성이나 동작을 하나로 추출해내는 작업을 말합니다. 추상적인 개념에 의존하여 설계해야 구현 부분에서의 유연한 개발이 가능합니다. 즉 세부적인 사물들의 공통적인 특징을 파악한 후, 하나의 묶음으로 만들어 내는 것이 추상화입니다.
코드를 재수정없이 재활용하는 것
접근 제어자를 통한 정보 은닉
정보 은닉화를 통해 높은 응집도와 낮은 결합도를 유지할 수 있도록 설계하는 것입니다.
쉽게 말하면 한 곳에서 변화가 일어나도 다른 곳에 미치는 사이드 이펙트를 최소화 시키는 것을 의미합니다. 즉, 객체 내부의 어떠한 동작에 대해 구현이 어떻게 되어있는지를 감추는 것입니다. 이를 통해 외부에서 뭔가 잘못 건드려 객체를 손상시키는 일을 방지할 수 있습니다.
결합도란 어떤 기능을 실행할 때 다른 클래스나 모듈에 얼마나 의존적인지를 나타내는 지표입니다.
여러 개체들이 지닌 공통된 특성을 부각시켜 하나의 개념이나 법칙으로 성립하는 과정(일반화라고도 합니다.)
상속의 개념은 부모클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게 하고 기능의 일부분을 변겨앻야 할 경우 상속받은 자식 클래스에서 해당 기능만 다시 수정하여 사용할 수 있게 하는 것입니다.
그러나 상속을 통한 재사용을 할 때 나타나는 단점이 명백합니다. 따라서 객체지향프로그래밍에서 코드 재사용을 목적으로 하는 상속 행위는 엄격히 금합니다.
그렇기에 상속은 반드시 재사용의 관점이 아닌 기능의 확장 관점으로 사용하여야 합니다.
서로 다른 클래스의 객체가 같은 동작 수행 명령을 받았을 때 각자의 특성에 맞는 방식으로 동작하는 것을 말합니다.
다형성을 구현하는 방법에는 대표적으로 3가지 오버로딩, 오버라이딩, 함수형 인터페이스가 있는데 이는 다른 글에서 작성해보겠습니다.
다형성은 상속과 함께 사용할 때 시너지가 엄청납니다. 다형성 구현을 통해 코드를 간결하게 해주고, 유연함을 갖추게 해줍니다. 또한 구체적으로 현재 어떤 클래스 객체가 참조되는 지는 무관하게 헐렁하게 프로그래밍하는 것이 가능합니다.