- Java 세팅 및 실습은 Windows 환경에서 IntelliJ를 통해 진행되었습니다.
1. OOP(객체지향프로그래밍) 개요
- 소프트웨어 개발에는 다양한 프로그래밍 패러다임이 있으며, 그 중에서도
절차지향 프로그래밍(PP: Procedural Programming)과 객체지향 프로그래밍(OOP: Object-Oriented Programming)은 가장 널리 알려진 두 가지 방식입니다.
- 이 두 패러다임은 문제를 해결하고 프로그램을 설계하는 방식에서 큰 차이를 보입니다.
1-1. 객체지향 프로그래밍(OOP) vs 절차지향 프로그래밍(PP)
절차지향 프로그래밍 (Procedural Programming)
절차지향 프로그래밍은 프로그램을 순차적인 명령어(절차, Procedure)로 구성하여 문제를 해결하는 방식입니다. 이 패러다임은 데이터를 함수와 절차로 나누고, 순차적인 흐름을 통해 프로그램이 실행됩니다.
객체지향 프로그래밍 (Object-Oriented Programming)
반면 객체지향 프로그래밍은 데이터를 중심으로 프로그램을 구성하며, 데이터와 그 데이터를 처리하는 방법을 하나의 단위(객체)로 묶어 캡슐화합니다. OOP는 데이터를 보호하고, 프로그램의 구조를 보다 명확하게 만드는 것을 목표로 합니다.
| 특징 | 절차지향 프로그래밍 (PP) | 객체지향 프로그래밍 (OOP) |
|---|
| 구조 | 함수와 절차 중심의 구조 | 객체와 클래스 중심의 구조 |
| 데이터 관리 | 전역 변수와 구조체를 사용하여 데이터 관리 | 객체 내부에서 데이터를 캡슐화하여 관리 |
| 재사용성 | 함수 단위로 코드 재사용 | 상속과 다형성을 통해 코드 재사용 가능 |
| 유지보수성 | 코드가 복잡해질수록 유지보수가 어려움 | 캡슐화와 모듈화를 통해 유지보수가 용이 |
| 확장성 | 함수 추가를 통해 확장 가능하나, 복잡해질 수 있음 | 상속과 다형성을 통해 쉽게 확장 가능 |
| 상태 변화 | 전역 변수나 인자의 변경을 통해 상태 변화 | 객체의 내부 상태 변화를 메서드를 통해 관리 |
| 프로그램 흐름 | 명령어와 함수 호출의 순차적 실행 | 객체 간의 상호작용을 통해 프로그램이 실행 |
| 예시 언어 | C, Pascal, Fortran 등 | Java, C++, Python, C# 등 |
1-2. 객체지향 프로그래밍(OOP)
- 객체지향 프로그래밍(OOP)은 소프트웨어 개발에서 데이터를 객체로 캡슐화하고, 이 객체들이 상호작용하여 프로그램을 구성하는 방식의 프로그래밍 패러다임입니다.
- OOP는 코드의 재사용성, 확장성, 유지보수성을 높이는 데 중점을 두고 있으며, 현대 소프트웨어 개발에서 가장 널리 사용되는 방법론 중 하나입니다.
OOP의 주요 개념
- 객체와 클래스
객체(Object): 객체는 상태(State)와 행위(Behavior)를 가지는 소프트웨어 단위입니다.
- 객체는 클래스의 인스턴스(instance)로, 클래스에서 정의된 속성(변수)과 메서드(함수)를 가지고 있습니다.
- 객체(Object)와 인스턴스(instance)는 엄격하게는 다른 개념이지만, 실무에서는 혼용해서 쓰여서 같은 의미라 보시면 됩니다.
클래스(Class): 클래스는 객체를 생성하기 위한 설계도(blueprint)입니다.
- 클래스는 객체의 상태를 나타내는 속성(필드 또는 멤버 변수)과 객체의 행위를 정의하는 메서드로 구성됩니다.
- 즉, 클래스는 특정 유형의 객체를 만들기 위한 청사진입니다.
- 객체지향 주요 특징
캡슐화(Encapsulation): 캡슐화는 객체의 데이터를 외부에서 직접 접근하지 못하게 하고, 객체 내부에서만 데이터와 메서드를 관리할 수 있도록 보호하는 개념입니다.
- 이를 통해 데이터의 무결성이 유지되고, 외부 코드와의 결합도를 낮출 수 있습니다.
상속(Inheritance): 상속은 새로운 클래스가 기존 클래스의 속성과 메서드를 물려받아 사용하는 기능입니다.
- 상속을 통해 코드의 재사용성이 높아지고, 계층적인 클래스 구조를 만들 수 있습니다.
다형성(Polymorphism): 다형성은 동일한 인터페이스나 부모 클래스를 공유하는 객체들이 다양한 형태로 동작할 수 있게 하는 특성입니다.
- 이는 주로 메서드 오버로딩(Overloading)과 메서드 오버라이딩(Overriding)을 통해 구현됩니다.
추상화(Abstraction): 추상화는 복잡한 시스템을 단순화하여 중요한 부분만을 드러내고, 세부 사항은 숨기는 개념입니다.
- 추상화를 통해 코드의 가독성이 높아지고, 유지보수가 용이해집니다.
1-3. 클래스(Class)와 객체(Object)
클래스(Class)
- 클래스는 객체지향 프로그래밍의 기본 단위로, 객체를 생성하기 위한 틀이나 설계도 역할을 합니다.
- 클래스는 두 가지 주요 구성 요소로 이루어집니다
- 필드(Field) 또는 속성(Attribute): 객체의 상태를 나타내는 변수입니다.
- 클래스 내에서 선언된 필드는 해당 클래스의 객체가 가질 수 있는 데이터(상태)를 정의합니다.
- 메서드(Method): 객체의 행위를 정의하는 함수입니다.
- 메서드는 객체가 수행할 수 있는 동작이나 기능을 정의하며, 클래스 내에 선언되어 있습니다.
- 예를 들어, Car라는 클래스를 정의할 때, Car 클래스는 자동차 객체를 생성하기 위한 설계도입니다.
- 이 클래스에는 자동차의 속성(예: 색상, 모델명)과 자동차가 수행할 수 있는 행동(예: 주행, 정지) 등이 포함될 수 있습니다.
public class Car {
String color;
String model;
public Car(String color, String model) {
this.color = color;
this.model = model;
}
public void drive() {
System.out.println(model + " is driving.");
}
public void stop() {
System.out.println(model + " has stopped.");
}
}
- 위 코드에서 Car 클래스는 color와 model이라는 속성을 가지며, drive()와 stop() 메서드를 통해 자동차의 행동을 정의하고 있습니다.
- 이 클래스에서 생성된 객체는 각각의 자동차를 나타내며, 해당 객체의 상태와 행동을 메서드를 통해 제어할 수 있습니다.
객체(Object)
- 객체는 클래스의 인스턴스(instance)로, 클래스에서 정의한 속성과 메서드를 실제로 사용할 수 있는 실체입니다.
- 객체는 특정 클래스의 구체적인 구현체이며, 메모리 상에 할당되어 실제 프로그램에서 사용됩니다.
- 객체는 다음과 같은 과정을 통해 생성됩니다:
Car myCar = new Car("Red", "Tesla Model 3");
- 위 코드에서 myCar는 Car 클래스의 인스턴스 객체이며, "Red" 색상을 가진 "Tesla Model 3" 모델의 자동차를 나타냅니다.
- 이 객체는 drive() 메서드를 호출하여 주행할 수 있으며, stop() 메서드를 호출하여 정지할 수 있습니다.
myCar.drive();
myCar.stop();
클래스 및 객체 활용 (배열)
- 클래스를 통해 생성한 인스턴스를 배열로 묶어 관리할 수 있습니다.
- 클래스는 참조형 타입처럼 사용할 수 있고 이를 통해 배열에서도 사용할 수 있게 됩니다.
Car car1 = new Car("Red", "Tesla Model 3");
Car car2 = new Car("Blue", "K3");
Car[] cars = new Car[2];
cars[0] = car1
cars[1] = car2
- 위 예시처럼 클래스를 하나의 타입처럼 취급하여 이용할 수 있습니다.
- 이때, car1과 car2에 저장되는 값은 메모리 주소를 나타내는
참조값이 저장됩니다. (다음 포스팅에서 다시 자세히 다룰 예정입니다.)
마무리
- 초급 단계에서는 클래스와 객체지향프로그래밍을 중심으로 내용들을 정리할 예정입니다.
- 이번 포스팅에서는 개요에 해당하는 내용들을 정리해보았고, 다음 포스팅부터는 기본형 변수와 참조형 변수에 대해서 먼저 정리해보는 시간을 가져보려합니다.