무지개 곰
무지개곰의 성장이야기
무지개 곰
250x250
  • 분류 전체보기
    • 블록체인 공부
      • BlockChain
      • Ethereum
    • IT공부
      • Java
      • JavaScript
      • HTML + CSS
      • React
      • 프로그래머스 (TypeScript)
    • 독서
    • 영어 공부
      • 1일 1 작문
      • 영어 짧은 글
    • 홍보
hELLO · Designed By 정상우.
무지개 곰

무지개곰의 성장이야기

[Java] Java의 다형성 이해하기
IT공부/Java

[Java] Java의 다형성 이해하기

2022. 7. 11. 12:00
728x90

다형성 이해하기

  • 메서드 오버 라이딩
  • 업 캐스팅
  • 다형성이란?
  • 다운 캐스팅 (instanceof)

메서드 오버 라이딩

부모 클래스에서 정의된 메서드 중에서 자식 클래스에서 기능이 맞지 않거나 추가적인 기능이 필요한 경우 메서드를 재정의 하는 것을 의미합니다. 단 오버 로딩(Overloading)과 다르게 입력받는 매개변수가 동일하여야 합니다.

public class Character{
    String name;
    public void attack(){
        System.out.println("주먹을 휘둘렀습니다.");
    }
}

public class Warrior extends Character{
    //오버라이딩
    public void attack(){
        System.out.println("검을 휘둘렀습니다.");
    }
    public void defence(){
        System.out.println("공격을 막았습니다.");
    }
}

public class Wizard extends Character{
    public void attack(){
        System.out.println("지팡이를 휘둘렀습니다.");
    }
    public void magic(){
        System.out.println("파이어 볼을 사용하였습니다.");
    }
}

위의 예시는 Character라는 부모 클래스와 상속을 받은 Warrior라는 자식 클래스가 있습니다. 두 클래스 모드 attack이라는 함수를 가지고 있습니다. 자식 클래스에서는 attack을 호출하면 주먹이 아닌 검을 휘두르게 하고 싶은 경우 위의 예시처럼 선언을 하게 되고 이를 오버 라이딩이라고 합니다.


업 캐스팅

업 캐스팅은 상속에서 자주 쓰이는 묵시적 형 변환이라고 생각하시면 됩니다. 변수를 선언할 때 클래스 형을 부모 클래스 즉 상위 클래스로 선언을 하지만 인스턴스 생성은 자식 클래스 즉 하위 클래스로 생성할 수 있습니다.

public class GameMake{
    public static void main(String[] args){
        Character firstCharacter = new Warrior();
        
        Warrior secondCharacter = new Character(); //불가능
    }
}

위와 같이 Warrior 클래스의 인스턴스를 만드는데 클래스 선언은 Character 클래스로 할 수 있습니다. 다만 반대의 경우는 불가능합니다. 비유를 한다면 모든 전사는 캐릭터이지만 모든 캐릭터가 전사는 아니기 때문에 상위 클래스로만 선언이 가능합니다.

public class GameMake{
    public static void main(String[] args){
        Character firstCharacter = new Warrior();
        Character secondCharacter = new Character();
        
        firstCharacter.attack();
        secondCharacter.attack();
        /*출력
        검을 휘둘렀습니다.
        주먹을 휘둘렀습니다.
        */
    }
}

선언된 클래스는 Character이지만 인스턴스는 다르기 때문에 인스턴스에 맞는 메서드가 호출되어 firstCharacter의 경우 검을 휘둘렀다는 문구가 나오게 되고 secondCharacter의 경우 주먹을 휘둘렀다는 문구가 나오게 됩니다.


다형성이란?

자바 코딩을 할 때 하나의 코드가 여러 가지 자료형으로 구현되어 실행되는 것을 다형성이라고 합니다.

public class GameMake{
    public static void main(String[] args){
        Character firstCharacter = new Warrior();
        Character secondCharacter = new Character();
        
        GameMake gameMake = new GameMake();
        gameMake.characterAttack(firstCharacter);
        gameMake.characterAttack(secondCharacter);
    }
    
    public void characterAttack(Character character){
        character.attack();
    }
}

위의 예시는 하나의 클래스를 상속받은 여러 클래스가 있는 경우 각 클래스마다 같은 이름의 서로 다른 메서드 즉 오버 라이딩된 메서드를 인스턴스에 따라 구현이 다르게 되는 기능을 보였습니다. characterAttack이라는 메서드에 입력받는 변수는 Character클래스로 받게 됩니다. 업 캐스팅에서도 말씀드렸듯 선언한 클래스는 같지만 인스턴스가 다르기 때문에 characterAttack메서드를 실행 시 인스턴스에 맞는 attack메서드를 불러오게 됩니다. 이러한 기능을 다형성이라고 합니다.


다운 캐스팅 (instanceof)

다운 캐스팅은 업 캐스팅된 변수에서 사용할 수 없는 자식 클래스 즉 하위 클래스에만 존재하는 변수 혹은 메서드를 사용하기 위해 클래스 형을 하위 클래스 형으로 변형하는 것입니다. 단순한 형 변환과 비슷합니다.

public class Character{
    String name;
    public void attack(){
        System.out.println("주먹을 휘둘렀습니다.");
    }
}

public class Warrior extends Character{
    //오버라이딩
    public void attack(){
        System.out.println("검을 휘둘렀습니다.");
    }
    public void defence(){
        System.out.println("공격을 막았습니다.");
    }
}

public class Wizard extends Character{
    public void attack(){
        System.out.println("지팡이를 휘둘렀습니다.");
    }
    public void magic(){
        System.out.println("파이어 볼을 사용하였습니다.");
    }
}

부모 클래스에는 defence메서드와 magic메서드는 존재하지 않습니다. 따라서 Warrior와 Wizard를 Character클래스로 선언 시 defence메서드와 magic메서드를 사용할 수 없습니다. 이 두 함수를 사용하기 위해서 Character로 선언된 변수를 형 변환하도록 하겠습니다.

public class GameMake{
    public static void main(String[] args){
        Character firstCharacter = new Warrior();
        Character secondCharacter = new Character();
        Character thirdCharacter = new Wizard();
        
        Warrior warrior = (Warrior)firstCharacter;
        warrior.defence(); //불가능
    }
}

위의 경우처럼 기존의 형 변환처럼 다운 캐스팅을 하고 나서 메서드를 불러올 수 있습니다. 하지만 이런 경우 업 캐스팅을 한 이유가 없습니다. 그렇기 때문에 사용하는 예약어 instanceof가 있습니다.

public class GameMake{
    public static void main(String[] args){
        GameMake gameMake = new GameMake();
        Character firstCharacter = new Warrior();
        Character secondCharacter = new Character();
        Character thirdCharacter = new Wizard();
        
        gameMake.skill(firstCharacter);
        gameMake.skill(secondCharacter);
        gameMake.skill(thirdCharacter);
        /*출력
        공격을 막았습니다.
        기술이 없습니다.
        파이어 볼을 사용하였습니다.
        */      
    }
    public void skill(Character character){
        if(character instanceof Warrior){
            Warrior warrior = (Warrior)character;
            warrior.defence();
        }
        else if (character instanceof Wizard){
            Wizard wizard = (Wizard)character;
            wizard.magic();
        }
        else{
            System.out.println("기술이 없습니다.");
        }
    }
}

skill메서드에서 instanceof를 통하여 character가 어떠한 인스턴스를 가지는지 확인을 하여 인스턴스에 맞는 기술을 사용할 수 있도록 코딩을 해주었습니다. 위와 같이 사용을 하면 메서드가 작동하는 동안에만 다운 캐스팅이 진행되므로 메인 함수에서는 업 캐스팅 상태를 유지할 수 있습니다.

728x90
저작자표시 비영리 변경금지 (새창열림)
    'IT공부/Java' 카테고리의 다른 글
    • [Java] Java의 인터페이스 이해하기
    • [Java] Java의 추상 이해하기
    • [Java] Java의 상속 이해하기
    • [Java] Java의 ArrayList 이해하기
    무지개 곰
    무지개 곰
    java solidity react javascript등 프로그래밍 공부 기록

    티스토리툴바