본문 바로가기

JAVA/다형성(Polymorphism)

다형성(Polymorphism)

다형성

 

다형성

1. 영어로 poly(여러개) + morphism(형태) 의 합성어로, 하나의 객체가 여러 형태를 가질 수 있는 성질을 의미한다고 한다.

2. 자바에서의 다형성이란 상위 클래스 타입의 참조 변수로 하위 클래스의 객체를 참조할 수 있는 성질을 말함

 

예 : 상위 타입으로 하위 객체를 참조하기

class Friend {
	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 FriendTest {
	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 girlFriend = new GirlFriend(); 와 같이 상위 타입(Friend)으로 하위 객체(GirlFriend)를 참조하는 것이 다형성의 핵심임

* 다형성이 적용되면 참조 변수는 상위 클래스 타입이지만, 실제 호출되는 메서드는 오버라이딩된 하위 클래스의 메서드임


다형성이 왜 필요한가

1. 여러 타입의 객체를 하나의 타입으로 관리할 수 있음

Car[] cars = new Car[5];
cars[0] = new Sonata();
cars[1] = new Morning();
cars[2] = new Avante();
cars[3] = new Grandure();
cars[4] = new Porter();

for(Car car : cars) {
	car.move(); // 각자의 override 된 메서드가 실행된다
}

 

* Car 배열 하나로 다양한 자동차 객체를 통합적으로 관리할 수 있음

 

 

2. 메시지 수 감소 - > 코드 간결화

// 다형성이 미적용된 상태, 메서드명이 전부 다르다
cars[0].moveSonata();
cars[1].moveMorning();
cars[2].moveAvante();

// 다형성을 적용한 상태, 메서드명이 하나
for(Car car : cars) {
	car.move();
}

 

* 같은 메시지로 다양한 객체를 처리할 수 있어서 코드 유지보수성이 높아짐

 

 

3. 확장성 향상

public void move(Car car) {
	car.move();
}

// 기존 메서드를 그대로 재사용할 수 있음
move(new Sonata());
move(new Morning());
move(new Santafe());

 

* 새로운 객체가 생겨도 기존 메서드를 그대로 활용할 수 있어서 확장에 유리하다

 

 

4. 결합도를 낮춤 (결합도는 낮게, 응집도는 높게)

public class Payment {
	// 결제수단이 현금인 경우
    public void pay(현금) {
    	현금.결제진행();
    }
    
    // 결제수단이 카드인 경우
    public void pay(카드) {
    	카드.결제진행();
    }
    
    // 결제수단이 카카오페이인 경우
    public void pay(카카오페이) {
    	카카오페이.결제진행();
    }
}

// 카드결제 혹은 현금결제 둘 다 가능하도록 어느 한 쪽을 의존하지 않게 만든다
// 현금, 카드, 기타 등등이 결제수단을 상속받으면 된다
public void pay(결제수단) {
	결제수단.결제진행();
}

 

* 현금, 카드, 페이앱 등 다양한 결제수단이 Payment 인터페이스나 추상 클래스를 구현하면 어떠한 객체든 동일한 메서드로 처리할 수 있게 된다 (결제진행)

* 의존성을 줄여 유연하고 유지보수가 쉬운 설계를 하게끔 만든다


메서드 오버라이딩과 오버로딩의 다형성

1. 메서드 오버라이딩(재정의)

상속관계에서 부모의 메서드를 자식 클래스에서 재정의한다

class Animal {
	void sound() {
    	System.out.println("동물소리");
    }
}

class Dog extends Animal {
	void sound() {
    	System.out.println("멍멍");
    }
}

Animal a = new Dog();
a.sound(); // 멍멍

 

 

2. 메서드 오버로딩(중복정의)

같은 이름, 다른 매개변수 형태의 메서드 다중 정의

void print(String str) {

}
void print(int num) {

}
void print(String str, int num) {

}

 


정리

항목 설명
정의 하나의 타입(상위 타입)으로 여러 하위 타입 객체를 다룰 수 있는 특성
활용 기술 메서드 오버라이딩, 오버로딩, 업캐스팅
장점 확장성, 유지보수성, 코드 간결성, 결합도 감소
전제 조건 상속 또는 인터페이스 구현 관계

 

'JAVA > 다형성(Polymorphism)' 카테고리의 다른 글

instanceof  (0) 2026.04.17
참조 변수의 타입 변환(up-casting, down-casting)  (0) 2026.04.17