우선 객체지향을 설명하기 전에 객체지향의 반대말인 절차적 프로그래밍에 대해서 설명하겠습니다.
그러는 편이 왜 객체지향을 사용하는지 이해하기 편할것입니다.
📕절차적 프로그래밍
📗절차적 프로그래밍의 정의
물이 위에서 아래로 흐르는 것처럼 순차적인 처리가 중요시 되며 프로그램 전체가 유기적으로
연결되도록 만드는 프로그래밍 기법이다.
💡장점
- 컴퓨터의 처리 구조와 유사해 실행속도가 빠르다.
- 각 프로그램의 흐름을 쉽게 추적할 수 있다.
💡단점
- 각 코드가 매우 유기성이 높아 유지보수가 어렵다.
- 실행순서가 정해져 있으므로 코드의 순서가 바뀌면 동일한 결과를 보장하기 어렵다.
절차적 프로그래밍에서 절차는 함수를 의미한다.
절차적 프로그래밍이란, 반복되는 동작을 함수 및 프로시저 형태로 모듈화하여 사용하는 방식이다.
말이 어려우니까 예시를 들자면,
은행에서 계좌 관리 프로그램을 개발한다고 할때
계좌라는 자료형을 구현해야 하고, 계좌에 대한 함수를 구현해야 한다.
이 두 가지는 절차적 프로그래밍에서 따로 구분된다.
계좌는 계좌고, 계좌에 대한 함수는 논리적으로 묶여있을 수 없는 구조이기에, 동작이 추상적이다.
이러한 계좌와 계좌에 대한 함수를 묶기 위해서 '객체 지향 프로그래밍'이 등장했다.
📕객체 지향(Object-Oriented Programmin)
프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체로 만들고,
객체들 간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
대표적으로 많이 알려진 java 언어를 포함해서, Python, C++, C#, Kotiln 등이 있다.
💡장점
- 모듈화, 캡슐화로 인해 유지보수에 용이하다.
- 객체 자체가 하나의 프로그램이기에 재사용에 용이하다.
💡단점
- 대부분의 객제치향 프로그램은 속도가 상대적으로 느려지고, 메모리를 많이 사용하는 경향이 있다.
- 코드를 설계하고, 작성하는데 많은 시간이 소요된다.
📕객체
객체는 프로그램에서 사용되는 데이터 또는 식별자에 의해 참조되는 공간을 의미하며,
값을 저장할 변수(계좌)와 수행할 메서드(계좌에 대한 함수)를 서로 연관된 것들끼리 묶어서 만들어집니다.
여기서 핵심포인트는 객체 내부에 자료형 필드와 함수가 함께 존재하는 것입니다.
이렇게 되면 절차적 프로그래밍에서의 단점이었던 추상적이었던 동작도 훨씬 직관적으로 보이게 되어, 코드 가독성이 증가합니다.
이러한 방법은 중복되는 코드의 양을 줄여서, 유지보수가 용이하게 만들어줍니다.
이러한 객체들을 조립해서, 하나의 프로그래밍으로 만드는 것이 객체지향 프로그래밍이라고 할 수 있습니다.
📕객체지향 프로그래밍의 4가지 특징
- 추상화
- 캡슐화
- 상속
- 다형성
각 특징을 자세히 설명하겠습니다.
📗추상화 (Abstraction)
객체들이 공통적으로 필요로 하는 속성이나 동작을 하나로 추출해 내는 작업
즉 알고는 있지만, 정확하게 표현하기 힘든 것들을 중요한 부분이나 특징점으로 잡아 설명하는 것을 추상화한다고 할 수 있겠습니다.
프로그래밍에서 추상화는 클래스를 정의할 때 불필요한 부분들을 생략하고 객체의 속성 중 중요한 것에만 중점을 두어 개략화 하는 것을 말합니다.
쉽게 예를 들자면, 삼성폰, 아이폰이라는 객체가 있을 때, 이 객체들을 하나로 묶을 때 공통적인 특징을 휴대폰으로 묶어서 이름을 붙이는 것을 추상화라고 할 수 있습니다.
이처럼 공통된 기능을 휴대폰에서 미리 구현을 하고, 상속을 통해서 공통된 기능을 삼성폰,아이폰에 이어주면
삼성폰과 아이폰은 각자의 고유기능을 집중적으로 개발할 수 있습니다.
이렇게 되면 공통된 기능을 다시 정의할 필요가 없기에, 코드의 중복이 줄어들고,
코드의 재사용이 용이해지는 장점이 있습니다.
즉 추상화로 구현해 두면, 새로운 객체를 만들 때, 클래스의 고유기능만 새로 만들어주고,
공통된 기능은 상속을 통해서 이용가능합니다.
📗상속 (Inheritance)
여러 개체들이 지닌 공통된 특성을 부각시켜 하나의 개념이나 법칙으로 성립하는 과정입니다.
위에서 설명한 삼성폰->휴대폰->통신기기->전자제품으로 이어지는 관계가 상속의 예라고 할 수 있습니다.
만약 삼성폰, 휴대혼, 통신기기, 전자제품은 모두 중복된 속성들이 있습니다.
이러한 속성들을 class 마다 만들어주기보다는 공통된 속성들을 하나로 모아놓은 클래스를 만들어서, 그 클래스를 상속하면 아주 효율적인 프로그래밍이 가능합니다.
상속을 통해서 하위클래스는 상위 클래스의 변수와 기능을 물려받아서, 재사용할 수 있습니다.
이렇게 상속을 통해서 코드의 중복을 제거할 수 있습니다.
📗다형성 (Polymorphism)
프로그래밍에서의 다형성이란 같은 자료형에 여러 가지 타입의 데이터를 대입하여 다양한 결과를 얻어낼 수 있는 성질을 의미합니다.
비유적으로 표현하면, 한명의 남자는 어떠한 상황에서 여러가지 역할이 있습니다.
누군가에게는 친구가, 자식에게는 아버지, 동아리에는 동호회 리더, 아내에게는 남편, 부모님에게는 자식이 될 수 있습니다.
이처럼 객체도 상황에 따라 여러가지 형태를 가질 수 있다는 것이 다형성의 핵심입니다.
대표적인 예로는 메서드 오버라이딩과 메서드 오버로딩이 있습니다.
💡메서드 오버라이딩
- 부모 클래스의 메서드를 자식 클래스에서 재정의해서 사용하는 것을 말하며, 자식 클래스는 부모 클래스의 메서드를 재활용하면서, 독자적인 기능을 추가할 수 있다.
💡메서드 오버로딩
- 같은 이름의 메서드를 다양한 매개변수 타입과 개수로 오버로딩하여 사용하는 것을 말하며,
오버로딩은 메서드 이름을 동일하게 유지하면서도, 다양한 상황에서 유연하게 대응할 수 있는 방법을 제공한다.
위 예시는 메서드 오버라이딩입니다.
메서드 오버라이딩의 예에는 휴대폰 클래스에서는 ringBell이라는 메서드가 있다고 가정하면,
삼성폰과 아이폰은 휴대폰 클래스를 상속받으며, 각각의 폰마다 벨소리가 다르기에, ringBell 메서드를 오버라이딩해서,
그들의 상황에 맞게 재정의해서 사용할 수 있습니다.
위 예시는 메서드 오버로딩입니다.
메서드 오버로딩의 예에는 번역기 클래스에는 translate라는 메서드가 있다고 가정합시다.
translate에는 숫자를 문자열로 번역해야 하고, 날짜를 문자열로 번역해야 하는 등 여러 가지 번역작업을 합니다.
이를 위해 translate 메서드를 오버로딩해서, 매개변수 타입에 따라 다르게 동작하도록 합니다.
이렇게 적절하게 다형성을 사용하면 코드의 재사용성과 유연성을 높이고, 불필요한 코드 중복과 결합도를 낮춰서 유지보수성을 높일 수 있습니다.
하지만 무분별한 오버로딩은 코드의 동작을 이해하는데 어려움을 줄 수 있으므로, 적절하게 사용해야 합니다.
📗캡슐화 (Encapsultaiton)
객체지향에서의 캡슐화는 데이터와 메서드를 하나의 단위로 묶어, 외부에서 접근하지 못하도록 보호하는 개념입니다.
아래 그림처럼 데이터와 메서드를 한 곳에 모아 관리하는 것입니다.
알약을 예로 들면, 우리는 알약 안에 어떠한 구성물질로 알약이 구성되어 있는지 알 수없고, 그 안의 내용물은 캡슐을 통해서
안전하게 보호되고 있습니다.
캡슐화는 외부에서 알 필요가 없는 부분을 감춤으로써 대상을 단순화하는 추상화의 한 종류입니다.
그렇다면 왜 캡슐화를 해야 할까요?
💡데이터 보호
- 외부로부터 클래스에 정의된 속성과 기능들을 보호
💡데이터 은닉
- 내부의 동작을 감추고 외부에는 필요한 부분만 노출
캡슐화가 중요한 이유는 불안정한 부분과 안정적인 부분을 분리해서 변경의 영향을 통제할 수 있기 때문입니다.
불안정한 부분은 객체 내부로 추상화해서 변경을 최소화하고, 안전한 부분은 외부에 공개합니다.
이렇게 객체의 외부와 내부를 구분해서, 구현을 변경할 수 있는 폭은 넓어지고, 변경의 영향을 통제할 수 있습니다.
그리고 캡슐화를 통해서 코드 작성 이후 추가적인 요구사항에 유연하게 대처할 수 있습니다.
✔️정리
- 객체는 데이터와 동작들을 묶어서 하나로 관리하고, 이러한 객체를 조립해서 프로그래밍하는 것이 객체지향프로그래밍이다.
- 객체지향프로그래밍에는 4가지 특징이 있다.
- 추상화, 상속, 다형성, 캡슐화
- 객체지향프로그래밍은 유연하고, 코드의 재사용을 줄이고, 코드의 가독성을 높이며, 유지보수를 용이하게 만드는 것이 목적이다.
'Computer Science > OOP' 카테고리의 다른 글
객체지향의 5가지 설계 원칙 [ S.O.L.I.D] (3) | 2023.05.29 |
---|