객체 지향 프로그래밍을 쉽게 이해하려면 코딩 패러다임을 알고 가면 좋을 거 같다.
코딩 패러다임이란 프로그래밍을 하는 방식이나 스타일을 의미한다. 즉, 코드를 작성하고 구성하는 철학적 접근 방식이라고 할 수 있다.
프로그래밍 언어마다 특정 패러다임을 따르거나 여러 패러다임을 혼합해서 지원할 수도 있다.
순차적 프로그래밍과 비 구조적 프로그래밍은 개념적으로는 다르나 비슷하게 지칭하므로 함께 묶어서 설명하겠다. 순차적 프로그래밍은 말 그대로 순차적으로 흘러가는 프로그래밍 구조를 의미한다. 보통 코딩 패러다임을 설명할 때 가장 초기에 등장한 코딩 패러다임이라고 부른다. 그도 그럴 것이 모든 프로그램은(그 어떠한 프로그램이든 간에) 코드를 순서대로 읽는다. 이 코딩 패러다임에서는 구조라는 개념이 없다. 그로 인해서 코드는 goto 문을 사용해서 코드를 짜게 된다. 문제는 여기서 벌어지는데 규모가 커지면 커질수록 goto 문이 범람하게 된다면 이미 그건 프로그래밍 보단 거의 실뜨기에 가까워진다. a에서 c로 갔다가 다시 b로... 따라서 사람들은 코드의 중복을 최대한 피하기 위해서 코드를 단위화할 방법을 모색하게 되었다.
다음으로 나온 코딩 패러다임은 절차적 프로그래밍이다. 절차적 프로그램은 프로시저(Procedure는 쉽게 설명하면 함수라고 생각한다. 다만 반환값이 없고 실행이 주가 되는 함수를 의미한다.)를 이용하여 작성하는 프로그래밍 스타일이다. (여담으로 많은 사람들이 객체 지향의 반대 개념은 절차적 프로그래밍으로 알 고 있는데 아니다. 절차적 프로그래밍의 관점이 프로시저에서 객체로 확장된 것에 가깝기에 일치한다고 볼 수는 없어도 서로 공유하는 부분이 차이보다 더 많다.) 절차적 프로그래밍도 순차적인 실행 흐름을 기반으로 하기 때문에, 코드가 많아질수록 흐름을 이해 하기 어려운 문제가 남아있었다.
이게 조금 더 발전한 형식이 구조적 프로그래밍이다. 절차적 프로그래밍이 함수를 기준으로 나뉜다면 구조적 프로그램은 모듈을 기준으로 나뉜다. 코드를 논리적인 블록(함수, 조건문, 반복문)으로 구성하여 유지 보수를 용이하게 했고 재사용성도 증가시켰다. goto 문 사용을 배제하고 if-else, for, while 사용으로 코드 흐름을 명확하게 구분했다. 하지만 데이터와 함수가 분리되어 있는 단점이 있었다. 해결책은 생각보다 간단했다. 특정 개념의 함수와 자료형을 함께 묶어서 관리하면 되지 않나 하는 것이다.
그리하여 탄생한 것이 객체 지향 프로그래밍(Object-Oriented Programming, OOP)이다.
객체 지향 프로그래밍에서 중요한 점은 모든 객체는 그 내부에 자료형(Field)과 함수(Method)가 존재한다. 이로 인해서 책이라는 자료를 객체 모델로 만든다면 그 책의 쪽수나, 이름과 같은 자료형 뿐만 아니라 책을 읽기, 책을 만들기 등의 함수들 역시 "책"이라는 객체로 묶어 놓는 것이다. 이렇게 객체 지향 프로그램은 가능한 모든 물리적, 논리적 요소들을 객체로 만들려고 한다. 일단 객체라는 한 개체로 완성되면 그 객체는 다른 객체로 부터 높은 수준의 독립성을 완성했다고 할 수 있다. 이렇게 하면 코딩할때 극 초반에만 조금 불편해진다. 그러나 시간이 지날수록 중복코딩이 굉장히 줄게되며 객체와 객체간에 독립성이 확립되므로 유지보수에 도움이된다.
코딩이 순차적 -> 절차적 -> 구조적 -> 객체 지향 프로그래밍으로 발전하였다.
객체 지향 프로그래밍은 객체(Object) 중심으로 데이터를 속성과 메서드로 묶어 관리하는 프로그래밍 방식이다. 캡슐화, 상속, 다형성, 추상화를 통해 코드 재사용 성과 유지 보수성을 높인다. 대표적인 객체 지향 언어로 Java, C# 등이 있다
간단한 예시로는 "자동차" 객체를 만든다면

using System;
public class Car
{
// 속성(멤버 변수)
public string _color { get; set; }
public int _speed { get; set; }
public int _fuel { get; set; }
// 생성자
public Car(string color, int speed = 0, int fuel)
{
Color = color;
Speed = speed;
Fuel = fuel;
}
// 가속 메서드
public void Accelerate()
{
if (_fuel > 0) // 연료가 있으면
{
_speed += 10;
_fuel -= 1; // 연료가 1만큼 감소
}
else
{
Console.WriteLine("연료가 없습니다.");
}
}
// 감속 메서드
public void Decelerate()
{
if (_speed > 0)
{
_speed -= 5;
if (_speed < 0) _speed = 0; // 속도가 0보다 작아지지 않도록 처리
}
else
{
Console.WriteLine("차가 이미 정지해 있습니다.");
}
}
// 정지 메서드
public void Stop()
{
_speed = 0;
Console.WriteLine("차가 정지했습니다.");
}
}
class Program
{
static void Main(string[] args)
{
// 객체 생성
Car myCar = new Car("Red", 10, 5);
Car yourCar = new Car("Blue", 50, 3);
// 객체의 메서드 호출
myCar.Accelerate();
myCar.Accelerate();
myCar.Decelerate();
myCar.Stop();
yourCar.Accelerate();
yourCar.Accelerate();
yourCar.Decelerate();
yourCar.Stop();
}
}