본문 바로가기
프로그래밍/Java

[Java] 다형성의 이해와 활용

by 코딩중독 2023. 11. 15.

목차

    다형성이란 무엇인가?

    다형성이란 단어의 의미는 '같은 종이면서 어떤 형태나 형질이 다양하게 나타나는 현상' 을 얘기한다.

     

    이와 비슷한 맥락으로 자바에서의 다형성이란 상위클래스가 동일한 메시지로 하위클래스를 서로 다르게 동작 시키는 의미로 이해하면 된다. 대표적인 예로 인터페이스, 추상클래스, 오버로딩, 오버라이딩, 업캐스팅, 다운캐스팅 등이 모두 다형성에 속해 있다.

     

    다형성의 장점

    1. 유지보수가 쉽다.
    2. 확장이 용이하다.

     

    다형성의 전제 조건

    1. 상속관계(extends)에 있어야 한다.
    2. 재정의(Override)가 가능하다. (필수 X)
    3. 업캐스팅(Upcasting)
    4. 동적바인딩 : 런타임 시점에 메서드가 결정된다.

     

    다형성의 활용(예시)

    1. 추상클래스 생성

    public abstract class Animal {
    
        public abstract void eat();
    
        public void move() {
            System.out.println("이동을 한다.");
        }
    
    }

     

    하나의 추상메서드와 하나의 구현메서드를 생성한다.

     

    2. 추상클래스를 상속받는 2개의 클래스 생성

    public class Dog extends Animal {
    
        @Override
        public void eat() {
            System.out.println("강아지 밥을 먹는다.");
        }
    
    }
    
    public class Cat extends Animal {
    
        public void night() {
            System.out.println("야행성 동물이다.");
        }
    
        @Override
        public void eat() {
            System.out.println("고양이 밥을 먹는다.");
        }
    }

     

    추상클래스인 Animal을 상속받은 Dog와 Cat 클래스는 추상메서드인 eat()를 필수적으로 재정의해야 한다.

     

    3. 준비된 클래스를 실행하는 메인클래스

    public class AbstractTest {
    
        public static void main(String[] args) {
    
            // 추상클래스는 단독으로 객체를 생성할 수 없다.
    //        Animal ani = new Animal();
    
            // 추상클래스는 부모의 역할은 할 수 있다.
            Animal animal = new Dog();
            animal.eat();   // 강아지 밥을 먹는다.
            animal.move();  // 이동을 한다.
    
            animal = new Cat();
            animal.eat();   // 고양이 밥을 먹는다.
            animal.move();  // 이동을 한다.
            ((Cat)animal).night();  // 야행성 동물이다.
    
        }
    
    }

     

    • 추상클래스는 단독으로 객체를 생성할 수 없다.
    • 추상클래스는 부모의 역할은 할 수 있다. (추상클래스인 Animal 클래스로 Dog, Cat 클래스 객체 생성)
    • 추상클래스인 Animal 클래스의 구현메서드는 자식클래스인 Dog, Cat에서 동일하게 사용이 가능하다.
    • 자식클래스인 Dog, Cat에서 재정의한 추상메서드 eat()은 각 클래스에서 재정의한 내용이 출력된다.
    • Cat 클래스에서 단독으로 생성된 구현메서드 night()는 Cat클래스를 다운캐스팅 해서 사용할 수 있다.

     

    다형성을 인수로 사용하는 예

    public class AbstractTest {
    
        public static void main(String[] args) {
            Animal animal = new Dog();
            polymorphismPrint(animal);
            animal = new Cat();
            polymorphismPrint(animal);
        }
    
        private static void polymorphismPrint(Animal animal) {
            animal.eat();
            if (animal instanceof Cat) {
                ((Cat) animal).night();
            }
        }
    
    }

     

    • polymorphismPrint() 함수에 Animal 클래스를 인수로 받게되면 위와 동일하게 생성된 객체에서 재정의된 eat()가 출력된다.
    • instanceof 연산자를 이용해서 객체가 어떤 클래스인지 확인하여 Cat 클래스가 인수로 들어오게 되면 night() 를 출력한다.

     

    마치며...

    추상클래스와 인터페이스를 사용하면서 다형성이라는 개념에 대해서는 정확하게 인지하지 못하고 버릇처럼 사용했었다.

    다형성에 대해 정확히 이해하게 된다면 외부API를 사용할 때에도 많은 도움이 될 것 같다.