[java]-Polymorphism(다형성)

자바 객체지향 프로그래밍에서 polymorphism(다형성)이 갖는 의미와 장점을 이해할 수 있다.

Polymorphism

GOALS:

  • 자바 객체지향 프로그래밍에서 polymorphism(다형성)이 갖는 의미와 장점을 이해할 수 있다.
  • 참조변수의 타입 변환에 대한 내용을 이해하고, 업캐스팅과 다운캐스팅의 차이를 설명할 수 있다.
  • instanceof 연산자를 언제 어떻게 활용할 수 있는지 이해하고 설명할 수 있다.
  • 예제 코드를 구현하며 polymorphism(다형성)이 어떻게 활용되는지 이해할 수 있다.

자바에서 polymorphism은 한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든 것.
구체적으론 상위 클래스 타입의 참조변수를 통해서 하위 클래스의 객체를 참조할 수 있도록 허용한 것.

class Friend {
    Friend(){
        System.out.println("Friend class의 생성자");
    }
    public void friendInfo() {
        System.out.println("나는 당신의 친구입니다.");
    }
}
 
class BoyFriend extends Friend {
 
    public void friendInfo() {
        System.out.println("나는 당신의 남자친구입니다.");
    }
}
 
class GirlFriend extends Friend {
 
    public void friendInfo() {
        System.out.println("나는 당신의 여자친구입니다.");
    }
}
 
public class test {
 
    public static void main(String[] args) {
        Friend friend = new Friend(); // 객체 타입과 참조변수 타입의 일치
        BoyFriend boyfriend = new BoyFriend();
        Friend girlfriend = new GirlFriend(); // 객체 타입과 참조변수 타입의 불일치
 
        friend.friendInfo();
        boyfriend.friendInfo();
        girlfriend.friendInfo();
    }
}
//출력값
Friend 생성자
Friend 생성자
Friend 생성자
나는 당신의 친구입니다.
나는 당신의 남자친구입니다.
나는 당신의 여자친구입니다.

위의 코드를 예시로 보자.
먼저 특이한 점은 GirlFriend 클래스의 인스턴스로 생성 후에 Friend 타입의 참조변수 girlfriend에 할당하고 있는 모습을 볼 수 있다.
출력값을 보면 알 수 있듯이 각각의 클래스를 인스턴스로 생성한 것을 알 수 있고,
이 경우는 상위 클래스를 참조변수의 타입으로 지정했기 때문에 상위 클래스 타입의 참조변수로 하위 클래스의 객체를 참조하는 것이 된다.

아무튼 너무 이해가 안갈 수 있지만 결국 polymorphism의 핵심은 하나의 객체가 여러가지 형태를 가질 수 있다는 것이다.


instanceof

그리고 이런 참조변수는 상속 관계에 있는 상위 클래스 - 하위 클래스 사이에서 타입 변환이 가능하다.
뭐 하위→상위는 업캐스팅이며 괄호를 생략해도 되고, 상위→하위는 다운캐스팅이며 괄호를 생략하면 안된다.
이런 개념들이 있는데 이들은 기본적으로 상속 관계에서 나와 타입이 변환되냐라서 이 관계에 대한 이론을 기억하고,
직접 부딪치며 보는 게 훨씬 도움 될 것들이다.

다만 다른 라이브러리나 다른 코드를 보고 쓰는 경우에는
이 관계를 파악하기 어렵기 때문에 캐스팅이 가능한지 여부를 instanceof 연산자를 boolean을 통해서 확인할 수 있다.


마지막으로 polymorphism을 활용한 간단한 코드 예제를 보면서 마무리 해보자.

public class PolymorphismEx {
  public static void main(String[] args) {
    Customer customer = new Customer();
    customer.buyCoffee(new Americano());
    customer.buyCoffee(new CaffeLatte());
 
    System.out.println("현재 잔액은 " + customer.money + "원 입니다.");
  }
}
 
class Coffee {
  int price;
 
  public Coffee(int price) {
    this.price = price;
  }
}
 
class Americano extends Coffee {
  public Americano() {
    super(4000); // 상위 클래스 Coffee의 생성자를 호출
  }
 
  public String toString() {return "아메리카노";}; //Object클래스 toString()메서드 오버라이딩
};
 
class CaffeLatte extends Coffee {
  public CaffeLatte() {
    super(5000);
  }
 
  public String toString() {return "카페라떼";};
};
 
class Customer {
  int money = 50000;
 
  void buyCoffee(Coffee coffee) {
    if (money < coffee.price) { // 물건 가격보다 돈이 없는 경우
      System.out.println("잔액이 부족합니다.");
      return;
    }
    money = money - coffee.price; // 가진 돈 - 커피 가격
    System.out.println(coffee + "를 구입했습니다.");
  }
}
// 출력값
아메리카노를 구입했습니다.
카페라떼를 구입했습니다.
현재 잔액은 41000원 입니다.
Comments

첫번째 댓글을 남겨주세요 :)

Post comment

0/500