[Java 초급] 7. 초급 과정 총정리 & 좋은 객체지향프로그래밍(OOP)의 원칙들

Kyung Jae, Cheong·2024년 8월 22일
0
post-thumbnail

객체지향프로그래밍(OOP) 총정리

  • Java 객체지향 프로그래밍(OOP)은 소프트웨어 개발에서 중요한 패러다임으로, 프로그램을 객체 단위로 구성하여 데이터와 행위를 캡슐화하고, 상속과 다형성을 통해 코드의 재사용성과 유지보수성을 높이는 것을 목표로 합니다.
  • 지금까지 다룬 주요 개념을 종합적으로 간단하게 정리하고, 좋은 객체지향 프로그래밍(OOP)을 위한 특징과 원칙들을 정리해보겠습니다.

1. 클래스와 객체

  • 클래스는 객체를 생성하기 위한 설계도로, 속성(필드)과 메서드(행위)를 포함합니다.
  • 객체는 클래스의 인스턴스로, 클래스에 정의된 속성과 메서드를 실제로 사용할 수 있는 실체입니다.

2. 절차지향 프로그래밍 vs 객체지향 프로그래밍

  • 절차지향 프로그래밍: 함수와 절차를 중심으로 프로그램을 구성.
  • 객체지향 프로그래밍: 데이터를 중심으로 프로그램을 구성하고, 데이터와 데이터를 처리하는 방법을 객체 단위로 캡슐화.

3. 변수와 메모리 구조

  • 기본형 변수: 실제 값을 저장하며, 스택 메모리 영역에 저장됩니다.
  • 참조형 변수: 객체의 주소를 저장하며, 객체는 힙 메모리 영역에 저장됩니다.
  • 변수의 선언 위치에 따라 지역 변수, 멤버 변수(인스턴스 변수, 클래스 변수), 매개변수 등으로 구분됩니다.

4. 제어자 (Modifiers)

  • 접근 제어자:
    • public, protected, default, private
    • Top-Level 클래스에서는 publicdefault만 사용 가능.
  • 기타 제어자:
    • static, final, abstract, synchronized, volatile, transient, native, strictfp, 등
      • abstractfinal은 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)에 대해서 정리해보았습니다.
    • 아직은 부족한 것도 많고 배워야할 것들이 많지만, 그래도 공부할수록 흥미를 많이 느끼고 있는 것 같습니다.
    • 참고로 그동안 파이썬만 공부하고 사용해왔던 입장에선 이러한 원칙들이 크게 중요하지는 않아서 개념들을 제대로 이해할 수 없었지만, 자바를 공부함으로써 이러한 개념들을 훨씬 깊게 잘 이해할 수 있었던것 같습니다.
  • 추후에 시간이 허락하는 대로 자바프로그래밍에 관한 내용들을 정리해 나아가도록 하겠습니다. 모두들 화이팅입니다 !
profile
일 때문에 포스팅은 잠시 쉬어요 ㅠ 바쁘다 바빠 모두들 화이팅! // Machine Learning (AI) Engineer & BackEnd Engineer (Entry)

0개의 댓글