안녕하세요. J4J입니다.
이번 포스팅은 객체지향 프로그래밍의 특징 중 하나인 다형성에 대해 적어보는 시간을 가져보려고 합니다.
다형성이란?
다형성이라고 하는 것은 다형성이라는 말을 그대로 풀이하여 여러 가지 형태를 가질 수 있는 특성을 의미합니다.
다른 표현으로는 자바에서 하나의 인스턴스를 생성할 때 한 클래스에 대해서만 생성하는 것이 아니라 여러 클래스에 대해 인스턴스를 생성할 수 있다는 것을 말합니다.
무슨 말인지 이해가 되지 않으실 것 같아 바로 코드로 표현해보겠습니다.
package oop;
public class Animal {
String zooName = "J4J Zoo";
public void getZooName() {
System.out.println(zooName);
}
public void getName() {
System.out.println("애니뭘~");
}
}
package oop;
public class Tiger extends Animal { // Animal 상속받기
String zooName = "Tiger Zoo";
@Override
public void getName() {
System.out.println("타이걸~");
}
public void getSpecies() {
System.out.println("대관령 호랑이");
}
}
package oop;
public class Lion extends Animal { // Animal 상속받기
@Override
public void getName() {
System.out.println("래이온~");
}
public void getScream() {
System.out.println("크어어어어어어오오어옹!");
}
}
package oop;
public class Polymorphism {
public static void main(String[] args) {
Animal animal = new Animal(); // 익숙한 인스턴스 생성 방법
Animal tiger = new Tiger(); // 익숙치 않은 인스턴스 생성 방법
Animal lion = new Lion(); // 익숙치 않은 인스턴스 생성 방법
// 첫 번째 특징
System.out.println(tiger.zooName); // J4J Zoo, 부모 클래스 변수만 사용 가능
// 두 번째 특징
animal.getZooName(); // J4J Zoo
tiger.getZooName(); // J4J Zoo
animal.getName(); // 애니뭘~
tiger.getName(); // 타이걸~
tiger.getSpecies(); // Error, 부모 클래스에서 사용되지 않는 메서드 이름 사용 불가
// 두 번째 특징 해결법
Lion realLion = (Lion)lion; // 캐스팅
realLion.getZooName(); // J4J Zoo
realLion.getName(); // 래이온~
realLion.getScream(); // 크어어어어어어오오어옹!
}
}
위의 코드를 보시면 Animal과 Animal을 상속받은 Tiger, Lion이라는 클래스를 확인하실 수 있습니다.
그리고 Polymorphism클래스를 보시면 익숙치 않은 인스턴스 생성 코드가 있을 것입니다.
보통 Animal클래스에 대한 인스턴스를 생성한다고 하면 Animal animal = new Animal()처럼 변수 타입과 new 뒤의 레퍼런스가 동일한 형태로 생성됩니다.
하지만 익숙하지 않게 Animal()대신에 Tiger()와 Lion()이 오는 것을 확인하실 수 있고 이와 같이 "부모클래스 변수명 = new 자식클래스"의 모습을 가지는 특성을 다형성이라고 부릅니다.
특징
다형성은 기본적으로 상속, 오버라이딩, 캐스팅에 대해 알고 있어야 됩니다.
※ 상속에 대해 모른다면? [Java] 자바기초 - 객체지향(OOP) - 상속화(Inheritance)
※ 오버라이딩에 대해 모른다면? [Java] 자바기초 - 오버라이딩과 오버로딩(overriding/overloading)
※ 캐스팅에 대해 모른다면? [Java] 자바기초 - 형 변환(Promotion/Casting)
첫 번째 특징은 부모 클래스의 변수만 사용할 수 있다는 것입니다.
위의 코드를 보시면 Animal클래스에 zooName이라는 값에 "J4J Zoo"라는 값을 저장해놨습니다.
그리고 Tiger클래스의 zooName에는 "Tiger Zoo"라는 값을 저장해놨습니다.
하지만 Polymorphism클래스의 첫 번째 특징이 주석으로 된 코드 하단에 다형성이 적용된 tiger변수로 zooName을 출력했을 때 "Tiger Zoo"가 아니라 "J4J Zoo"의 값이 출력되고 있습니다.
이처럼 변수 값은 항상 부모 클래스에 선언된 것만 사용할 수 있다는 것을 확인할 수 있습니다.
두 번째 특징은 부모 클래스에 선언된 메서드 이름만 사용할 수 있다는 것입니다.
Polymorphism클래스의 두 번째 특징이 주석으로 된 코드 하단을 보시면 상속의 특성이 적용되어 animal과 tiger모두 getZooName()과 getName()을 문제없이 사용할 수 있는 것을 볼 수 있습니다.
그리고 getName()에는 오버 라이딩의 특성까지도 확인할 수 있습니다.
하지만 tiger의 getSpecies() 메서드를 사용할 때는 에러가 나는 것을 확인할 수 있습니다.
왜냐하면 변수 타입에 해당하는 Animal클래스는 getSpecies라는 이름으로 정의된 메서드가 없기 때문입니다.
어? 그럼 자식 클래스에서 선언된 메서드들을 사용 불가한 건가요?
이 대답은 No입니다.
자식 클래스에서 선언된 메서드들도 사용할 수 있는 데 사용하기 위해서는 캐스팅을 이용하면 됩니다.
Polymorphism클래스의 두 번째 특징 해결법이 주석으로 된 코드 하단과 같이 캐스팅을 이용하여 Lion클래스에 정의되어 있는 것을 모두 사용할 수도 있습니다.
사용 이유
지금까지 내용으로만 보시면 아니, 말도 어렵고 이해하기도 힘들고 동일 클래스 명으로 인스턴스를 생성하면 되지 굳이 이런 식으로 표현해야 되나?라는 불만 섞인 생각들이 들 수 있습니다.
하지만 다형성을 사용하는 이유에는 개별적인 클래스들을 하나의 클래스로 통합 관리하기 위해서라는 명확한 이유가 존재합니다.
자바로 프로그래밍을 하다 보면 배열, 리스트 등을 사용하여 동일한 변수 타입으로 선언된 변수들을 관리해야 되는 상황이 많이 발생합니다.
이러 상황 속에서 서로 다른 클래스들을 더 효율적으로 관리하고자 다형성을 사용하게 됩니다.
코드로 보여드리겠습니다.
package oop;
import java.util.ArrayList;
import java.util.List;
public class Zoo {
public void getAnimalName(Animal animal) {
animal.getName();
}
public static void main(String[] args) {
Tiger tiger = new Tiger();
Lion lion = new Lion();
Zoo zoo = new Zoo();
zoo.getAnimalName(tiger); // 타이걸~
zoo.getAnimalName(lion); // 래이온~
Animal[] animalArray = new Animal[]{tiger, lion}; // Animal을 담는 배열
List<Animal> animalList = new ArrayList<Animal>(); // Animal을 담는 리스트
animalList.add(tiger);
animalList.add(lion);
}
}
위의 코드처럼 메서드의 파라미터로 Animal을 받을 때 다형성을 통해 Animal의 자식 클래스들을 사용할 수 있고 배열, 리스트 등에도 서로 다른 클래스지만 같이 담아 통합 관리를 할 수 있습니다.
이처럼 서로 다른 클래스들을 하나의 클래스로 관리함으로 써 코드 관리를 수월하게 하는 이점을 가져오게 됩니다.
정리
이상으로 객체지향 프로그래밍의 특징 중 하나인 다형성에 대해 간단하게 알아보는 시간이었습니다.
읽어주셔서 감사합니다.
'Language > Java' 카테고리의 다른 글
[Java] 자바기초 - 컬렉션(Collection) (0) | 2020.12.31 |
---|---|
[Java] 자바기초 - 제네릭(Generic) (0) | 2020.12.28 |
[Java] 자바기초 - 객체지향(OOP) - 상속화(Inheritance) (0) | 2020.12.26 |
[Java] 자바기초 - 객체지향(OOP) - 추상화(Abstraction) (0) | 2020.12.23 |
[Java] 자바기초 - 객체지향(OOP) - 캡슐화(Encapsulation) (0) | 2020.12.22 |
댓글