절차 지향은 일정한 단계에 따라 개체를 순차적으로 처리하여 프로그램의 전체를 유기적으로 연결한다.
프로그램이 위에서부터 아래로 실행되기 때문에 TOP-DOWN 접근방식을 취하게 된다.
절차 지향 프로그래밍에서 "절차"는 함수를 의미한다.
반복되는 동작을 함수 및 프로시저 형태로 모듈화하여 사용하여 코드의 길이를 크개 줄일 수 있다.
또한 컴퓨터의 처리구조와 유사하기 때문에 실행 속도가 빠르다는 장점이 존재한다.
그러나 유지, 보수가 어렵고 실행 순서가 정해져 있기 때문에 비효율적이다.
전체 구성 요소가 연결되어 있다는 것은, 하나의 문제점이 프로그램 전체의 문제점이 됨을 의미한다.
문제를 해결하기 위해서는 프로그램 전체의 수리가 필요하다. 따라서 유지 보수와 디버깅이 매우 어렵다.
마찬가지로, 정해진 실행 순서로 인해서 코드의 순서가 바뀌면 결과가 달라질 가능성이 높다.
즉, 절차 지향 언어는 언어 자체의 융통성이 부족하여 생산 효율이 떨어진다.
도서관의 '도서 관리 프로그램'을 개발한다고 가정한다.
'책'이라는 자료형과 책에 대한 함수를 구현해야 한다. 절차 지향 프로그래밍에서는 책이라는 자료형과 책 관련 함수는 따로 위치하기 때문에, 같은 소스코드 파일 내에 있더라도 이 둘의 연관 여부는 단 번에 알아차리기 어렵다. 즉, 논리적으로 묶여있을 수 없는 구조이기 때문에 동작이 추상적이다.
✔️ 이를 묶기 위한 패러다임으로 '객체 지향 프로그래밍' 이 등장하게 된 것이다.
프로그램을 다수의 객체로 만들고, 객체들이 서로 상호작용하도록 만드는 프로그래밍이다.
절차 지향 프로그래밍은 기능을 중심으로 작성하였지만 객체 지향은 데이터 중심으로 동작시킨다.
자료형과 함수를 객체 형태로 묶어서 관리하기 위해 객체 지향 프로그래밍 패러다임이 등장하였다.
객체부터 디자인된 후 조립되는 형식이기 때문에 BOTTOM-UP 접근 방식을 가지고 있다.
객체 내부에는 자료형 필드와 함수가 함께 존재하는 것이다.
가능한 모든 물리적, 논리적 요소를 객체로 만드는 것이 객체지향 프로그래밍이다.
이를 통해 객체 간의 독립성이 뚜렷해지고, 중복되는 코드의 양이 줄어든다.
따라서 유지 보수가 용이하다는 장점이 있다.
'도서 관리 프로그램'을 객체 지향으로 구현하게 되면 책의 제목, 저자, 페이지수와 같은 자료형 필드와 대출하기, 반납하기 등의 메소드를 책이라는 객체에 함께 묶어서 관리하는 것이 가능해진다.
객체를 사용하면 추상적이었던 동작도 훨씬 직관적으로 보이게 되어 코드 가독성이 증가한다.
추상화 (Abstraction)
객체들이 공통적으로 필요로 하는 속성이나 동작을 하나로 추출해내는 작업이다. 즉, 공통의 속성과 기능을 묶어서 이름을 붙이는 것이다. 객체 지향적 관점에서는 클래스를 정의하는 것이 바로 추상화라고 할 수 있다. 추상적인 개념에 의존하여 설계가 이루어질 때, 유연함의 장점을 가질 수 있다.
캡슐화 (Encapsulation)
변수와 함수를 클래스로 묶는 것을 말한다.
정보를 은닉하여 높은 응집도, 낮은 결합도를 유지할 수 있도록 설계할 수 있다.
한 곳에서 일어난 변화가 다른 곳에 영향을 미치는 사이드 이펙트를 최소화 시키는 것을 의미한다. 즉, 객체 내부의 어떤 동작에 대한 구현이 어떻게 되어있는지 감추는 것이다.
이를 통해 외부에서 뭔가 잘못 건드려 객체를 손상시키는 일을 방지할 수 있다.
상속 (Inheritance)
여러 개체들이 지닌 공통된 특성을 부각시켜서 하나의 개념이나 법칙으로 성립하는 과정(일반화)이다.
자식 클래스는 부모 클래스의 필드나 메소드를 이어 받거나 조금 수정해서 사용할 수 있다.
상속을 활용하면 상위 클래스의 구현을 활용함으로써, 코드 재사용이 용이해진다.
상속에 따른 단점 또한 명확하다.
부모 클래스에 따라 자식 클래스가 영향을 받기 때문에 부모 클래스의 변경이 불편하다.
유사한 기능을 확장하는 경우 필요 이상의 불필요한 클래스를 만들어야할 수도 있다.
다형성 (Polymorphism)
서로 다른 클래스의 객체가 같은 동작 수행 명령을 받았을 때, 각자의 특성에 맞는 방식으로 동작하는 것이다. 같은 이름의 변수나 함수가 상황에 따라서 다르게 동작할 수 있다.
- 오버라이딩 (Overriding) : 상위 클래스의 메소드를 하위 클래스가 재정의해서 사용
- 오버로딩 (Overloading) : 같은 이름의 메소드가 매개변수의 개수와 유형에 따라 다르게 동작