다형성, 여러가지 모양을 갖는 것을 뜻한다.
"한가지의 물체가 여러가지 모양을 갖는다." 이 문장을 마음에 새기며 다형성에 대해서 이해하도록 하자.
다형성이란?
자바 프로그래밍에서 다형성은 한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 만든 것을 뜻한다.
즉, 상위 클래스 타입의 참조변수를 통해 하위 클래스의 객체를 참조 할 수 있도록 한 것을 다형성이라고 한다.
나는 스포츠를 좋아한다.를 두고 참조변수를 만들어보자
어떤사람은 스포츠 중에서 축구를 좋아한다.
또 어떤사람은 스포츠 중에서 농구를 좋아한다.
또는 스포츠 그 자체를 좋아할 수 있다.
class Sports {
public void favorite() {
System.out.println("나는 스포츠를 좋아합니다.");
}
}
class Football extends Sports {
public void favorite() {
System.out.println("나는 축구를 좋아합니다.");
}
}
class Basketball extends Sports {
public void favorite() {
System.out.println("나는 농구를 좋아합니다.");
}
}
public class Sportsisgood {
public static void main(String[] args) {
// 객체 타입(Sprots)과 참조변수 타입(Sports)의 일치
Sports sports = new Sports();
Football football = new Football();
// 객체 타입(Basketball)과 참조변수 타입(Sports)의 불일치
Sports basketball = new Basketball();
sports.favorite();
football.favorite();
basketball.favorite();
}
}
다음과 같이 상위클래스 타입의 참조변수로 하위 클래스의 객체를 참조하는 것이 다형성의 핵심이다.
또한 상위 클래스를 참조 변수 타입으로 지정했기 때문에 참조변수의 멤버의 수는 상위클래스의 멤버의 수가 된다.
참조변수의 타입 변환
참조변수의 타입 변환은 다형성을 이해하기 위해 필수적으로 알아야하는 개념이다.
타입 변환은 사용할 수 있는 멤버의 개수를 조절하는 것을 의미하기 때문이다.
타입 변환을 하기 위한 조건은 다음과 같다.
- 상속관계에 있는 상위클래스와 하위클래스 사이에서만 가능하다
- 하위 클래스 타입에서 상위 클래스 타입으로의 변환(업캐스팅)은 형변환 연산자(괄호)를 생략
- 상위 클래스 타입에서 하위 클래스 타입으로의 변환(다운캐스팅)은 형변환 연산자(괄호) 필수
public class Sportsisgood {
public static void main(String[] args) {
Football football = new Football();
Sports sports = Football; // 또는 (Sports) Football();
//상위 클래스 Sports 타입으로 변환
Football test = (Sports) sports;
// 하위 클래스 Football 타입으로 변환 (형변환 연산자 생략 불가능)
}
}
class Sports {
public void favorite() {
System.out.println("나는 스포츠를 좋아합니다.");
}
public void favorite() {
System.out.println("나는 동계 스포츠를 좋아합니다.");
}
public void favorite() {
System.out.println("나는 하계 스포츠를 좋아합니다.");
}
}
class Football extends Sports {
public void favorite() {
System.out.println("나는 축구를 좋아합니다.");
}
}
다형성의 활용 예제
나는 과일가게를 운영한다.
우리 가게에서는 사과와 복숭아를 판매하고 있다.
만약 내가 손님에게 사과 또는 복숭아를 판매하려고 한다면 코드를 어떻게 작성해야할까?
우선 과일이라는 범주의 클래스가 있어야 한다. 그리고 사과와 복숭아 클래스가 있어야 한다.
또한 이걸 구입하는 손님이 있어야 한다.
이것을 코드로 작성하면 다음과 같을 것이다.
class Fruits {
}
class Apple extends Fruits{};
class Apple extends Peach{};
class Customer{
}
손님은 과일을 구매해야한다.
과일을 구매하기 위해서는 과일 가격이 매겨져야한다.
그것은 다음과 같다.
package Java;
public class Main {
public static void main(String[] args) {
Customer customer = new Customer();
customer.buyFruits(new Apple());
customer.buyFruits(new Peach());
System.out.println("현재 잔액은 " + customer.money + "원 입니다.");
}
}
class Fruits {
int price;
public Fruits(int price){
this.price = price; // 과일의 가격을 담을 변수
}
}
class Apple extends Fruits{
public Apple() {
super(4000);
}
}
class Peach extends Fruits {
public Peach() {
super(5000);
}
}
class Customer{
int money = 30000;
void buyFruits(Apple apple) { // 아메리카노 구입
money = money - apple.price;
}
void buyFruits(Peach peach) { // 카페라테 구입
money = money - peach.price;
}
}
그러나 이렇게 코딩할 경우 과일이 하나 추가 될 때마다 메서드와 클래스를 계속해서 추가해줘야한다.
이것은 어마무시한 비효율이다.
우리는 다형성을 활용하여 buyFruits()메서드를 보다 재활용 할 수 있다.
void buyFruits(Apple apple) { // 아메리카노 구입
money = money - apple.price;
}
void buyFruits(Peach peach) { // 카페라테 구입
money = money - peach.price;
}
이것을
void buyFruits(Fruits fruits) { // 아메리카노 구입
money = money - fruits.price;
}
이렇게 바꿔보면 어떻게 될까?
결과적으로 같은 값이 나온다.
이것을 토대로 banana라는 품목을 추가해보겠다.
class Banana extends Fruits{
public Banana() {
super(2000);
}
}
다음과 같이 화면이 출력된다.
'Back-End > Java' 카테고리의 다른 글
[Java /자바] 추상화와 추상 클래스 (0) | 2022.09.13 |
---|---|
[자바 / Java] instanceof 연산자 (0) | 2022.09.08 |
[자바 / Java] 접근제어자(Acess Modifier) (0) | 2022.09.07 |
[자바 / Java] 캡슐화(capsule)와 패키지(package) (0) | 2022.09.06 |
[자바 / Java] super 키워드와 super() (0) | 2022.09.06 |