Java

[중앙정보처리학원] Java* 다형성 (Polymorphism)

해보구 2024. 4. 22. 17:11

다형성이란?

 

다형성이란 "객체가 여러 형태를 가진다" 라는 의미로 해석되며, 하나의 객체가 여러가지 타입으로 사용되는 것을 의미함

다형성은 상속을 전제 조건으로함

다형성을 위해 자바는 자식 클래스가 부모 클래스의 타입을 가질 수 있도록 허용

즉, 부모 타입에 모든 자식 객체가 대입 될 수 있다.

부모 타입 변수에 어떠한 자식 객체든 들어갈 수 있다, 라는 개념이 다형성이다.

 

tips

// 다형성을 통해 이종(다른)모음 배열을 구현할 수 있음.
// 객체타입에서 다운캐스팅의 전제조건: 반드시 상속관계가 있어야 하며
// 자식객체가 부모타입으로 업캐스팅 된 것만 내릴 수 있음
// 즉 부모객체를 자식타입으로 내릴 수는 없다.
// 다형성은 객체의 교혼성을 높여주며
// 객체가 특정 부품객체에 종속되지 않도록 하게 해준다.

 

 

 

코드를 통해서 간단하게 어떤 개념인지 확인해 보자.

class A {}
class B extends A {}
class C extends A {}
class D extends B {}
class E extends C {}

public class Basic {
	//다형성을 적용하지 않았을 때
	A a = new A();
	B b = new B();
	C c = new C();
	D d = new D();
	E e = new E();

	//다형성을 적용했을 때
	A v1 = new B(); //클래스 타입 B -> A타입으로 자동 형 변환(promotion)
	A v2 = new C();
	A v3 = new D();
	A v4 = new E();
}
다형성이 없을 때는 참조 변수의 타입을 객체에 맞게 작성해 주어야 한다.
하지만 다형성을 적용했다면?
최상위 부모인 A 타입에 모든 객체의 주소값이 저장될 수 있다.

 

 
 
 
다형성을 사용하는 이유

위 그림을 보면 Animal 이라는 부모 클래스가 있고, Dog, Cat, Duck 클래스가 존재한다.

모든 자식 클래스는 부모가 물려준 sound() 라는 메서드를 본인의 클래스에 맞게 재 정의해서

사용하고 있는 모습이다.

 

Dog dog = new Dog();
Cat cat = new Cat();
Duck duck = new Duck();

Animal[] animals = {dog, cat, duck};

 

각자 다른 세 개의 자식 객체를 하나의 배열에 넣고 싶다.

배열은 기본적으로 동종 모음 구조이다. 같은 타입 끼리만 배열에 모여 있을 수가 있는데,

배열을 부모 타입으로 선언했더니, 모든 자식의 객체가 하나의 배열에 모여 있을 수가 있다.

부모 타입으로 타입을 규격화 시켜 놓으니 훨씬 더 쉽게 객체들을 관리할 수 있다.

 

//매개변수에 다형성이 적용되어 있지 않다면
//메서드 오버로딩을 통해 일일히 구현 해 주어야함.
public void makeSound(Dog dog) {...}

public void makeSound(Cat cat) {...}

public void makeSound(Duck duck) {...}

////////////////////////////////////////////////////////////////

//매개변수에 다형성을 준 경우
public void makeSound(Animal animal) {
	animal.sound(); //dog, cat, duck 모두 sound() 호출 가능.
}

굳이 여러 개의 메서드를 선언할 필요 없이 하나의 메서드 만으로

여러 개의 객체를 받아 처리할 수 있다

 

 

instanceof 키워드

다형성이 적용 되었다면 부모와 연관이 있는 모든 자식 객체의 주소값이 저장되는 것이 가능하지만,

어떤 타입의 객체가 저장되는 지에 대한 확인이 필요할 때가 있다.

이 때 사용하는 키워드 instanceof 를 코드로 예시를 들어 설명한다.

 

public void sayHello(Animal ani) {
	if(ani instanceof Dog) {
		System.out.println("강아지가 꼬리를 흔들어요.");
	} else if(ani instanceof Cat) {
		System.out.println("고양이가 나를 못 본척 해요");
	} else if(ani instanceof Duck) {
		System.out.println("오리가 꽉꽉 울어요.");
	}
}

 

sayHello 메서드는 매개변수에 다형성이 적용되어 있다.

부모 타입인 Animal 변수가 선언되어 Dog, Cat, Duck 객체가 모두 전달이 가능하다.

하지만 어떤 객체냐에 따라 다른 인사법을 가지고 있기 때문에, 객체 구분이 필요하다.

이 때 instanceof 키워드를 사용하여 해당 객체가 어떤 타입을 가지고 있는 지를 물어 볼 수 있다.