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

Java 상속과 다형성

Java 상속과 다형성 — 중급

상속과 다형성

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

상속과 다형성은 객체 지향 프로그래밍(OOP)의 핵심 개념으로, 코드를 재사용하고 프로그램의 유지보수성을 높이는 데 필수적입니다. 실무에서 객체 지향 프로그래밍을 사용하지 않으면 코드가 중복되고 복잡해져, 나중에 수정이나 확장이 어려워질 수 있습니다. 예를 들어, 쇼핑몰 시스템에서 다양한 제품을 관리할 때, 상속과 다형성을 활용하면 코드의 중복을 줄이고 관리하기 쉬운 구조로 만들 수 있습니다.

상속이 없다면, 모든 제품의 속성을 일일이 정의해야 하며, 다형성이 없다면 각 제품의 행동을 개별적으로 구현해야 합니다. 결과적으로 코드의 가독성이 떨어지고, 버그가 발생할 확률이 높아집니다.

2. 핵심 개념 설명

  • 상속: 한 클래스가 다른 클래스의 속성과 메소드를 물려받는 개념입니다. 이를 통해 코드의 재사용성이 높아집니다.
  • - 비유: 부모가 자녀에게 유전자를 물려주는 것과 같습니다. 자녀는 부모의 특성을 이어받습니다.

  • 다형성: 동일한 메소드가 다양한 방식으로 동작할 수 있는 능력입니다. 이를 통해 코드의 유연성을 높일 수 있습니다.
  • - 비유: 한 사람이 여러 역할을 수행하는 것과 같습니다. 같은 이름의 메소드가 객체의 종류에 따라 다르게 동작합니다.

    용어설명
    상위 클래스다른 클래스에서 상속받는 클래스
    하위 클래스상위 클래스를 상속받아 확장하는 클래스
    오버라이딩하위 클래스에서 상위 클래스의 메소드를 재정의하는 것

    3. 기본 코드 예제

    다음은 상속과 다형성을 보여주는 간단한 코드입니다.

    class Animal {
        void sound() {
            System.out.println("동물이 소리를 냅니다.");
        }
    }
    
    class Dog extends Animal {
        @Override
        void sound() {
            System.out.println("멍멍");
        }
    }
    
    class Cat extends Animal {
        @Override
        void sound() {
            System.out.println("야옹");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Animal myDog = new Dog();  // Animal 타입의 Dog 객체 생성
            Animal myCat = new Cat();  // Animal 타입의 Cat 객체 생성
    
            myDog.sound();  // 멍멍 출력
            myCat.sound();  // 야옹 출력
        }
    }

    실행 결과

    멍멍
    야옹

    코드 동작 설명

    1. Animal 클래스 정의: 기본적인 소리 메소드를 포함합니다.
    2. Dog 클래스 정의: Animal 클래스를 상속받고 sound 메소드를 오버라이드합니다.
    3. Cat 클래스 정의: Animal 클래스를 상속받고 sound 메소드를 오버라이드합니다.
    4. Main 클래스에서 Dog와 Cat 객체를 Animal 타입으로 생성합니다.
    5. 각 객체에 대해 sound 메소드를 호출하여 해당 클래스의 소리를 출력합니다.
    6. 4. 실전 활용 예제

      예제 1: 쇼핑몰 장바구니 구현

      장바구니에는 여러 종류의 상품이 있을 수 있습니다. 상속과 다형성을 활용하여 다양한 상품을 정의할 수 있습니다.

      abstract class Product {
          String name;
          double price;
      
          Product(String name, double price) {
              this.name = name;
              this.price = price;
          }
      
          abstract void showInfo();
      }
      
      class Book extends Product {
          Book(String name, double price) {
              super(name, price);
          }
      
          @Override
          void showInfo() {
              System.out.println("책: " + name + ", 가격: " + price);
          }
      }
      
      class Electronics extends Product {
          Electronics(String name, double price) {
              super(name, price);
          }
      
          @Override
          void showInfo() {
              System.out.println("전자기기: " + name + ", 가격: " + price);
          }
      }
      
      public class ShoppingCart {
          public static void main(String[] args) {
              Product book = new Book("자바 프로그래밍", 25000);
              Product phone = new Electronics("스마트폰", 800000);
      
              book.showInfo();  // 책: 자바 프로그래밍, 가격: 25000 출력
              phone.showInfo(); // 전자기기: 스마트폰, 가격: 800000 출력
          }
      }

      예제 2: 동물원 관리 시스템

      동물원에서 다양한 동물의 행동을 관리할 때도 상속과 다형성을 활용할 수 있습니다.

      abstract class ZooAnimal {
          abstract void feed();
      }
      
      class Lion extends ZooAnimal {
          @Override
          void feed() {
              System.out.println("사자를 고기로 먹입니다.");
          }
      }
      
      class Elephant extends ZooAnimal {
          @Override
          void feed() {
              System.out.println("코끼리를 풀로 먹입니다.");
          }
      }
      
      public class Zoo {
          public static void main(String[] args) {
              ZooAnimal lion = new Lion();
              ZooAnimal elephant = new Elephant();
      
              lion.feed();      // 사자를 고기로 먹입니다. 출력
              elephant.feed();  // 코끼리를 풀로 먹입니다. 출력
          }
      }

      5. 흔한 실수와 주의사항

    7. 상속을 잘못 이해하기: 상속은 'is-a' 관계입니다. 예를 들어, Dog는 Animal의 한 종류이기 때문에 적절한 관계를 설정해야 합니다.
    8. - 잘못된 코드:

          class Car extends Animal {  // Car는 Animal이 아님
          }

      - 올바른 코드:

          class Dog extends Animal { 
          }
    9. 오버라이드 시 메소드 시그니처 불일치: 하위 클래스에서 메소드를 오버라이드할 때, 반드시 메소드 시그니처가 일치해야 합니다.
    10. - 잘못된 코드:

          class Dog extends Animal {
              void sound(int volume) {  // 시그니처 불일치
              }
          }

      - 올바른 코드:

          class Dog extends Animal {
              @Override
              void sound() {  // 메소드 시그니처 일치
              }
          }

      6. 정리

    11. 상속과 다형성은 코드의 재사용성과 유지보수성을 높여줍니다.
    12. 상속은 부모 클래스의 속성과 메소드를 물려받는 개념입니다.
    13. 다형성은 동일한 메소드가 서로 다른 객체에서 다르게 동작하는 특성입니다.
    14. 다음에 학습하면 좋은 주제는 인터페이스와 추상 클래스입니다. 이러한 개념은 상속과 다형성을 더욱 깊이 이해하는 데 도움이 됩니다.