[인프런 Java] 다형성 활용1

코드 속의 "진돌"·2024년 3월 21일
0
post-thumbnail

✅ 다형성 활용1


지금까지 학습한 다형성을 왜 사용하는지, 그 장점을 알아보기 위해 우선 다형성을 사용하지 않고 프로그램을 개발한 다음에 다형성을 사용하도록 코드를 변경해보자.

아주 단순하고 전통적인 동물 소리 문제로 접근해보자.

개, 고양이, 소의 울음 소리를 테스트하는 프로그램을 작성해보자. 먼저 다형성을 사용하지 않고 코드를 작성해보자.




✅ 예제1


✏️ Dog

package poly.ex1;

public class Dog {

  public void sound() {
    System.out.println("멍멍");
  }
}



✏️ Cat

package poly.ex1;

public class Cat {

  public void sound() {
    System.out.println("냐옹");
  }
}



✏️ Caw

package poly.ex1;

public class Caw {

  public void sound() {
    System.out.println("음매");
  }
}



✏️ AnimalSoundMain

package poly.ex1;

public class AnimalSoundMain {

  public static void main(String[] args) {
    Dog dog = new Dog();
    Cat cat = new Cat();
    Caw caw = new Caw();

    System.out.println("동물 소리 테스트 시작");
    dog.sound();
    System.out.println("동물 소리 테스트 종료");

    System.out.println("동물 소리 테스트 시작");
    cat.sound();
    System.out.println("동물 소리 테스트 종료");

    System.out.println("동물 소리 테스트 시작");
    caw.sound();
    System.out.println("동물 소리 테스트 종료");
  }
}



🖥️ 실행 결과



⚙️ 코드 설명

단순히 개, 고양이, 소 동물들의 울음 소리를 출력하는 프로그램이다. 만약 여기서 새로운 동물이 추가되면 어떻게 될까?

만약 기존 코드에 소가 없었다고 가정해보자. 소가 추가된다고 가정하면 Caw 클래스를 만들고 다음 코드도 추가해야한다.

// Caw를 생성하는 코드
Caw caw = new Caw();

// Caw를 사용하는 코드
System.out.println("동물 소리 테스트 시작");
caw.sound();
System.out.println("동물 소리 테스트 종료");

Caw를 생성하는 부분은 당연히 필요하니 크게 상관이 없지만, Dog, Cat, Caw를 사용해서 출력하는 부분은 계속 중복이 증가된다.



✏️ 중복 코드

System.out.println("동물 소리 테스트 시작");
dog.sound();
System.out.println("동물 소리 테스트 종료");

System.out.println("동물 소리 테스트 시작");
cat.sound(); 
System.out.println("동물 소리 테스트 종료");

...

이 부분의 중복을 제거할 수 있을까?

중복을 제거하기 위해서는 메서드를 사용하거나 또는 배열과 for문을 사용하면 된다.
그런데 Dog, Cat, Caw는 서로 완전히 다른 클래스다.




✅ 중복 제거 시도


✏️ 메서드로 중복 제거 시도

메서드를 사용하면 다음과 같이 매개변수의 클래스를 Caw, Dog, Cat 중에 하나로 정해야 한다.

private static void soundCaw(Caw caw) {
	System.out.println("동물 소리 테스트 시작");
	caw.sound();
	System.out.println("동물 소리 테스트 종료");
}

따라서 이 메서드는 Caw 전용 메서드가 되고 Dog, Cat은 인수로 사용할 수 없다.
Dog, Cat, Caw의 타입(클래스)이 서로 다르기 때문에 soundCaw 메서드를 함께 사용하는 것은 불가능하다.

✏️ 배열과 for문을 통한 중복 제거 시도

Caw[] cawArr = {cat, dog, caw};  // 컴파일 오류 발생!
System.out.println("동물 소리 테스트 시작");
	
for (Caw caw : cawArr) {
	cawArr.sound();
}
System.out.println("동물 소리 테스트 종료");

배열과 for문을 사용해서 중복을 제거하려고 해도 배열의 타입을 Dog, Cat, Caw 중에 하나로 지정해야 한다. 같은 Caw들을 배열에 담아서 처리하는 것은 가능하지만 타입이 서로 다른 Dog, Cat, Caw를 하나의 배열에 담는 것은 불가능하다.
결과적으로 지금 상황에서는 해결 방법이 없다. 새로운 동물이 추가될 때 마다 더 많은 중복 코드를 작성해야 한다.


지금까지 설명한 모든 중복 제거 시도가 Dog, Cat, Caw타입이 서로 다르기 때문에 불가능하다. 문제의 핵심은 바로 타입이 다르다는 점이다. 반대로 이야기하면 Dog, Cat, Caw가 모두 같은 타입을 사용할 수 있는 방법이 있다면 메서드와 배열을 활용해서 코드의 중복을 제거할 수 있다는 것이다.

다형성의 핵심은 다형적 참조와 메서드 오버라이딩이다. 이 둘을 활용하면 Dog, Cat, Caw가 모두 같은 타입을 사용하고, 각자 자신의 메서드도 호출할 수 있다.


출처 : 김영한의 실전 자바 - 기본편
https://www.inflearn.com/course/김영한의-실전-자바-기본편/dashboard

profile
매일 성장하는 주니어 개발자의 기록📝

0개의 댓글