본문 바로가기
Java

[JAVA] 자바의 다형성(Polymorphism) 이해하기: 개념부터 예제까지

by 임혁진 2025. 1. 11.

다형성은 자바 객체지향 프로그래밍에서 매우 중요한 개념 중 하나입니다.
이를 통해 객체가 다양한 형태를 가질 수 있으며, 유연하고 확장성 높은 코드를 작성할 수 있습니다.
이번 글에서는 다형성의 기본 개념, 예제, 그리고 활용 방법을 다루며,
관련된 핵심 주제인 instance of 연산자와 클래스 캐스팅 도 함께 설명하겠습니다.

1. 다형성(Polymorphism)

  • 정의: 객체가 다양한 형태를 가질 수 있는 성질.
  • 특징:
    • 자식 객체부모 타입을 가질 수 있다.
    • 부모 타입으로 선언된 변수는 부모 클래스의 메서드만 사용할 수 있다.
      단, 오버라이딩(Overriding) 된 메서드는 자식 클래스의 구현이 실행된다.
    • 상속 관계가 반드시 전제되어야 한다.

2. 클래스 형변환(Class Casting)

  • 다형성으로 인해 부모 타입으로 변환된 객체를 다시 자식 타입으로 변환하는 것.
  • 이를 통해 자식 클래스의 고유 메서드나 필드를 사용할 수 있다.
  • 주의: 다형성이 일어나지 않은 객체에 대해 형변환을 시도하면 ClassCastException 오류가 발생.

3. instanceof 연산자

  • 객체가 특정 클래스의 인스턴스인지 확인하는 연산자.
  • 다형성이 적용된 객체의 본래 타입을 확인할 때 사용.

다형성 기본 예제

클래스 구조

public class Parent {
    public void method01() {
        System.out.println("부모의 메서드 1번 실행");
    }

    public void method02() {
        System.out.println("부모의 메서드 2번 실행");
    }
}

public class Child extends Parent {
    @Override
    public void method02() {
        System.out.println("오버라이딩 된 2번 메서드 실행");
    }

    public void method03() {
        System.out.println("자식의 3번 메서드 실행");
    }
}

 

 

다형성 적용

public class MainClass {
    public static void main(String[] args) {
        Child child = new Child();

        // 자식 클래스 메서드 호출
        child.method01(); // 부모의 메서드 실행
        child.method02(); // 오버라이딩 된 메서드 실행
        child.method03(); // 자식의 메서드 실행

        System.out.println("----- 다형성 적용 -----");
        Parent p = child; // 자식 객체를 부모 타입으로 변환

        p.method01(); // 부모의 메서드
        p.method02(); // 오버라이딩 된 자식의 메서드
        // p.method03(); // 사용 불가 (부모 클래스에 정의되지 않음)
    }
}

클래스 형변환과 instanceof 사용

클래스 형변환

public class MainClass {
    public static void main(String[] args) {
        Parent p = new Child(); // 다형성 적용
        Child c = (Child) p;    // 형변환

        c.method01(); // 부모의 메서드
        c.method02(); // 오버라이딩 된 메서드
        c.method03(); // 자식의 고유 메서드
    }
}

 

형변환 예외 상황

public class MainClass {
    public static void main(String[] args) {
        Object o = new Object();

        // 형변환 시 오류 발생
        String s = (String) o; // ClassCastException
    }
}

 

 

instanceof 연산자

public static void checkInstance(Parent p) {
    if (p instanceof Child) {
        Child c = (Child) p;
        System.out.println("Child 타입: " + c);
    } else if (p instanceof Parent) {
        System.out.println("Parent 타입");
    }
}

다형성 활용 예제

Person 클래스 구조

public class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    String info() {
        return "이름: " + name + ", 나이: " + age;
    }
}

public class Student extends Person {
    String studentId;

    Student(String name, int age, String studentId) {
        super(name, age);
        this.studentId = studentId;
    }

    @Override
    String info() {
        return super.info() + ", 학번: " + studentId;
    }
}

활용 예제

public class MainClass {
    public static void main(String[] args) {
        Person s1 = new Student("홍길동", 20, "123123");
        Person s2 = new Student("홍길자", 30, "456456");

        // 배열 활용
        Person[] persons = {s1, s2};

        for (Person p : persons) {
            System.out.println(p.info());
        }
    }
}

요약

  1. 다형성은 객체가 다양한 형태를 가지는 성질로, 유연하고 재사용성 높은 코드를 작성할 수 있게 한다.
  2. 클래스 형변환을 통해 부모 타입으로 변환된 객체를 다시 자식 타입으로 변환할 수 있다.
  3. instanceof 연산자는 객체의 실제 타입을 확인하고 안전하게 형변환을 수행하는 데 도움을 준다.

활용 팁

  • 다형성을 통해 공통된 로직은 부모 클래스에, 특화된 로직은 자식 클래스에 구현하여 유지보수성을 높일 수 있습니다.
  • 형변환과 instanceof 연산자를 적절히 사용하여 안정성을 유지할 수 있다.