- Java 세팅 및 실습은 Windows 환경에서 IntelliJ를 통해 진행되었습니다.
객체지향프로그래밍(OOP) 총정리
- Java 객체지향 프로그래밍(OOP)은 소프트웨어 개발에서 중요한 패러다임으로, 프로그램을 객체 단위로 구성하여 데이터와 행위를 캡슐화하고, 상속과 다형성을 통해 코드의 재사용성과 유지보수성을 높이는 것을 목표로 합니다.
- 지금까지 다룬 주요 개념을 종합적으로 간단하게 정리하고, 좋은 객체지향 프로그래밍(OOP)을 위한 특징과 원칙들을 정리해보겠습니다.
1. 클래스와 객체
- 클래스는 객체를 생성하기 위한 설계도로, 속성(필드)과 메서드(행위)를 포함합니다.
- 객체는 클래스의 인스턴스로, 클래스에 정의된 속성과 메서드를 실제로 사용할 수 있는 실체입니다.
2. 절차지향 프로그래밍 vs 객체지향 프로그래밍
- 절차지향 프로그래밍: 함수와 절차를 중심으로 프로그램을 구성.
- 객체지향 프로그래밍: 데이터를 중심으로 프로그램을 구성하고, 데이터와 데이터를 처리하는 방법을 객체 단위로 캡슐화.
3. 변수와 메모리 구조
- 기본형 변수: 실제 값을 저장하며, 스택 메모리 영역에 저장됩니다.
- 참조형 변수: 객체의 주소를 저장하며, 객체는 힙 메모리 영역에 저장됩니다.
- 변수의 선언 위치에 따라 지역 변수, 멤버 변수(인스턴스 변수, 클래스 변수), 매개변수 등으로 구분됩니다.
4. 제어자 (Modifiers)
- 접근 제어자:
public
, protected
, default
, private
- Top-Level 클래스에서는
public
과 default
만 사용 가능.
- 기타 제어자:
static
, final
, abstract
, synchronized, volatile, transient, native, strictfp, 등
abstract
와 final
은 Top-Level 클래스에서도 사용 가능.
static
은 Top-Level 클래스에서는 사용할 수 없고, 내부 클래스나 메서드, 변수에 사용됩니다.
5. 다형성 (Polymorphism)
- 다형성의 개념: 동일한 인터페이스나 부모 클래스를 공유하는 객체들이 다양한 형태로 동작할 수 있는 능력.
- 다형적 참조: 부모 클래스 타입의 참조 변수로 자식 클래스의 객체를 참조할 수 있습니다.
업캐스팅
: 자식 클래스 타입의 객체를 부모 클래스 타입으로 변환.
다운캐스팅
: 부모 클래스 타입으로 업캐스팅된 객체를 다시 자식 클래스 타입으로 변환.
instanceof
연산자: 객체가 특정 클래스의 인스턴스인지 확인하여, 안전하게 다운캐스팅할 수 있도록 도와줍니다.
- 메서드 오버라이딩: 자식 클래스가 부모 클래스의 메서드를 재정의하여 자신만의 방식으로 동작하게 만듭니다.
6. 추상 클래스와 인터페이스
- 추상 클래스: 객체를 직접 생성할 수 없으며, 부분적으로 구현된 메서드와 추상 메서드를 포함합니다.
- 공통적인 행동과 속성을 여러 클래스가 공유할 수 있도록 하는 데 사용됩니다.
- 순수 추상 메서드: 구현이 없는 메서드로, 이를 포함한 클래스가 추상 클래스입니다.
- 인터페이스: 모든 메서드가 순수 추상 메서드로 이루어진 구조.
- 다중 상속을 지원하며, 클래스가 특정 동작을 구현하도록 강제합니다.
- Java 8 이후에는 기본 메서드와 static 메서드도 포함할 수 있습니다.
좋은 객체지향 프로그래밍이란?
- 좋은 객체지향 프로그래밍(OOP)이란, 객체지향의 원칙과 개념을 잘 적용하여 확장 가능하고 유지보수하기 쉬운 소프트웨어를 개발하는 것을 의미합니다.
- 좋은 OOP 설계를 위해서는 다음과 같은 원칙을 고려해야 합니다.
- 캡슐화: 객체의 내부 상태를 숨기고, 외부에서는 필요한 인터페이스를 통해서만 접근할 수 있도록 합니다. (접근제어자와 메서드를 활용합니다)
- 상속과 다형성: 공통된 속성과 메서드를 상속을 통해 재사용하고, 다형성을 활용하여 객체의 다양한 형태를 지원합니다.
- 단일 책임 원칙(SRP: Single Responsibility Principle): 클래스는 하나의 책임(역할)만 가져야 하며, 이로 인해 코드의 변화에 잘 대응할 수 있습니다.
- 개방-폐쇄 원칙(OCP: Open-Closed Principle): 기존 코드를 수정하지 않고, 기능을 확장할 수 있도록 설계합니다. 이는 다형성, 인터페이스, 추상 클래스 등을 통해 구현할 수 있습니다. (뒤에서 좀 더 자세히 다루겠습니다.)
- 의존성 역전 원칙(DIP: Dependency Inversion Principle): 상위 모듈이 하위 모듈에 의존하지 않고, 추상화된 인터페이스에 의존하도록 설계합니다.
- 인터페이스 분리 원칙(ISP: Interface Segregation Principle): 인터페이스는 클라이언트가 사용하지 않는 메서드에 의존하지 않도록 작게 분리해야 합니다.
OCP (Open-Closed Principle) 원칙
- OCP (Open-Closed Principle)는 객체지향 설계 원칙 중 하나로, "소프트웨어 요소는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다"는 원칙입니다.
- 이 원칙을 따르면 기존 코드를 수정하지 않고 새로운 기능을 추가할 수 있어, 코드의 유연성과 안정성을 크게 향상시킬 수 있습니다.
- 확장에 열려 있음(Open for extension): 새로운 기능을 추가할 수 있도록 설계해야 합니다.
- 변경에 닫혀 있음(Closed for modification): 기존 코드를 변경하지 않고도 새로운 기능을 확장할 수 있도록 해야 합니다.
OCP 원칙 구현 예시
- OCP 원칙은 추상화와 다형성을 통해 구현할 수 있습니다.
- 예를 들어, 새로운 기능을 추가할 때 기존 코드를 수정하지 않고, 새로운 클래스를 추가하는 방식으로 기능을 확장할 수 있습니다.
abstract class Shape {
public abstract void draw();
}
class Circle extends Shape {
@Override
public void draw() {
System.out.println("Drawing a circle.");
}
}
class Rectangle extends Shape {
@Override
public void draw() {
System.out.println("Drawing a rectangle.");
}
}
class Triangle extends Shape {
@Override
public void draw() {
System.out.println("Drawing a triangle.");
}
}
public class Main {
public static void drawShapes(List<Shape> shapes) {
for (Shape shape : shapes) {
shape.draw();
}
}
public static void main(String[] args) {
List<Shape> shapes = Arrays.asList(new Circle(), new Rectangle(), new Triangle());
drawShapes(shapes);
}
}
- 위 코드에서 Shape 클래스는 확장에 열려 있고, 새로운 도형인 Triangle 클래스는 기존 코드를 수정하지 않고도 추가할 수 있습니다. 이로써 OCP 원칙을 만족시킵니다.
결론 및 마무리
- Java 객체지향 프로그래밍(OOP)에서 클래스와 객체, 상속과 다형성, 추상 클래스와 인터페이스 등의 개념을 잘 이해하고 활용하는 것은 소프트웨어 설계의 핵심입니다.
- 좋은 OOP는 이러한 개념들을 적절히 사용하여 코드의 재사용성, 유연성, 유지보수성을 높이는 것이 목표입니다.
- 특히 OCP(Open-Closed Principle) 원칙을 준수함으로써, 소프트웨어를 변화에 잘 대응할 수 있도록 만들 수 있습니다. 이 모든 개념을 종합적으로 이해하고 실천함으로써, 더욱 견고하고 확장 가능한 소프트웨어를 설계할 수 있습니다.
- 이로써 자바 프로그래밍에서 가장 중요한 개념인 객체지향 프로그래밍(OOP)에 대해서 정리해보았습니다.
- 아직은 부족한 것도 많고 배워야할 것들이 많지만, 그래도 공부할수록 흥미를 많이 느끼고 있는 것 같습니다.
- 참고로 그동안 파이썬만 공부하고 사용해왔던 입장에선 이러한 원칙들이 크게 중요하지는 않아서 개념들을 제대로 이해할 수 없었지만, 자바를 공부함으로써 이러한 개념들을 훨씬 깊게 잘 이해할 수 있었던것 같습니다.
- 추후에 시간이 허락하는 대로 자바프로그래밍에 관한 내용들을 정리해 나아가도록 하겠습니다. 모두들 화이팅입니다 !