IMCAT.DEV
로그인 가입
Scala 중급 객체지향

Scala 객체 지향 프로그래밍 (OOP) 심화

Scala 객체 지향 프로그래밍 (OOP) 심화 — 중급

객체 지향 프로그래밍 (OOP) 심화

1. 도입 (왜 배워야 하는가)

객체 지향 프로그래밍(OOP)은 소프트웨어 개발의 주요 패러다임 중 하나로, 복잡한 시스템을 효율적으로 관리하고 유지보수하기 위해 필수적입니다. OOP를 이해하지 못하면 코드의 재사용성을 떨어뜨리고, 시스템의 확장성이 제한되며, 유지보수에 드는 비용이 증가하는 등의 문제가 발생할 수 있습니다. 예를 들어, 쇼핑몰 시스템을 구축할 때 장바구니, 상품, 사용자 등의 객체를 정의하고 이들 간의 관계를 명확히 하는 것이 중요합니다. OOP는 이러한 구조를 제공하여 코드의 가독성과 유지보수성을 높여줍니다.

2. 핵심 개념 설명

2.1 클래스와 객체

  • 클래스(Class): 객체를 생성하기 위한 청print. 예를 들어, 자동차라는 클래스를 만들면, 이 클래스를 바탕으로 여러 대의 자동차 객체를 생성할 수 있습니다.
  • 객체(Object): 클래스를 인스턴스화한 실체. 자동차 클래스에서 생성된 특정 차의 인스턴스가 객체입니다.
  • 2.2 상속(Inheritance)

  • 상위 클래스의 속성과 행동을 하위 클래스가 물려받는 기법입니다. 예를 들어, "동물"이라는 클래스를 만들고 "개"와 "고양이" 클래스를 상속받게 할 수 있습니다.
  • 2.3 다형성(Polymorphism)

  • 같은 인터페이스를 사용해 서로 다른 형태의 행동을 가능하게 합니다. 예를 들어, "그리다"라는 메서드는 "원", "사각형", "삼각형" 클래스에서 각각 다르게 구현될 수 있습니다.
  • 용어정의
    클래스객체를 생성하기 위한 설계도
    객체클래스의 인스턴스
    상속부모 클래스의 속성을 자식 클래스가 물려받는 것
    다형성동일한 메서드가 다른 클래스에서 다른 기능을 하는 것

    3. 기본 코드 예제

    아래는 클래스와 객체를 사용하는 간단한 예제입니다.

    // 자동차 클래스를 정의합니다.
    class Car(val brand: String, val model: String) {
      def displayInfo(): String = s"브랜드: $brand, 모델: $model"
    }
    
    // 자동차 객체를 생성합니다.
    val myCar = new Car("현대", "아반떼")
    
    // 자동차 정보를 출력합니다.
    println(myCar.displayInfo())
  • 실행 결과: 브랜드: 현대, 모델: 아반떼
  • 코드 설명:
  • - class Car(...): 자동차 클래스를 정의합니다. - val brand: String: 브랜드 속성을 정의합니다. - def displayInfo(): String = ...: 자동차 정보를 출력하는 메서드를 정의합니다. - val myCar = new Car(...): Car 클래스의 인스턴스를 생성합니다. - println(myCar.displayInfo()): 자동차 정보를 출력합니다.

    4. 실전 활용 예제

    4.1 쇼핑몰에서 장바구니 구현

    장바구니를 클래스로 정의하고, 상품을 추가하고 총 금액을 계산하는 기능을 구현해봅시다.

    class ShoppingCart {
      private var items: List[String] = List()
      private var totalPrice: Double = 0.0
    
      def addItem(item: String, price: Double): Unit = {
        items = items :+ item
        totalPrice += price
      }
    
      def getTotalPrice: Double = totalPrice
    }
    
    // 장바구니 객체 생성
    val cart = new ShoppingCart()
    cart.addItem("사과", 1000)
    cart.addItem("바나나", 1200)
    
    // 총 금액 출력
    println(s"총 금액: ${cart.getTotalPrice}원")
  • 실행 결과: 총 금액: 2200원
  • 4.2 게임 캐릭터 클래스

    게임에서 캐릭터를 정의하고, 공격 및 방어 메서드를 구현할 때 사용할 수 있습니다.

    class Character(val name: String, var health: Int) {
      def attack(target: Character, damage: Int): Unit = {
        target.health -= damage
        println(s"${name}가 ${target.name}에게 ${damage}의 피해를 주었습니다.")
      }
    }
    
    // 캐릭터 생성
    val hero = new Character("영웅", 100)
    val monster = new Character("괴물", 50)
    
    // 공격 수행
    hero.attack(monster, 20)
  • 실행 결과: 영웅가 괴물에게 20의 피해를 주었습니다.
  • 5. 흔한 실수와 주의사항

    실수 1: 잘못된 접근 제어자 사용

    class Example {
      private var number: Int = 10
      def getNumber(): Int = number // 올바른 접근
    }
    
    // 잘못된 접근
    println(example.number) // 오류 발생
  • 올바른 코드: getNumber() 메서드를 통해 접근해야 합니다.
  • 실수 2: 상속에서 메서드 오버라이드 실수

    class Parent {
      def greet(): String = "안녕하세요"
    }
    
    class Child extends Parent {
      // 오류: 메서드 시그니처가 다릅니다.
      def greet(name: String): String = s"안녕하세요, $name"
    }
  • 올바른 코드: greet(name: String) 메서드를 오버라이드하려면 override 키워드를 사용해야 합니다.
  • 6. 정리

  • OOP는 복잡한 시스템을 효율적으로 관리하고 유지보수하기 위한 필수적인 기술입니다.
  • 클래스, 객체, 상속, 다형성은 OOP의 핵심 개념입니다.
  • 실생활의 비유를 통해 OOP 개념을 이해하는 것이 중요합니다.
  • 다음에 학습하면 좋은 주제는 인터페이스, 특성(특성 프로그래밍), 컴포지션입니다. OOP의 심화된 개념을 이해하기 위해 이 주제들을 계속해서 탐구해 보세요.