다형성(polymophism)이란
하나의 객체가 여러가지 타입을 가질 수 있는 것을 의미한다.
자바에서는 다형성을 부모클래스 타입의 참조변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여
구현하고 있다.
같은코드에서 여러 실행결과가 나올 수 있으며 객체지향 프로그래밍의 유연성, 재활용성, 유지보수성에 기본이
되는 특징이다.
다형성은 상속, 추상화와 더불어 객체지향 프로그래밍을 구성하는 중요한 특징 중 하나이다.
다형성은 다양한 여러 클래스를 하나의 자료형(상위클래스)으로 선언하거나 형변환하여 각 클래스가 동일한
메소드를 오버라이딩한 경우, 하나의 코드가 다양한 구현을 실행할 수 있다.
유사한 클래스가 추가되는 경우 유지보수에 용이하고 각 자료형마다 다른 메소드를 호출하지 않으므로 코드에서
많은 if문이 사라진다.
참조변수의 다형성
자바에서는 다형성을 위해 부모클래스 타입의 참조변수로 자식 클래스 타입의 인스턴스를 참조할 수 있다.
//Animal Class
class Animal{
public void move() {
}
}
//Human Class
class Human extends Animal {
public void move() {
}
public void readBooks() {
}
}
//Tiger Class
class Tiger extends Animal {
public void move() {
}
public void hunting() {
}
}
//main
public class AnimalTest {
public static void main(String[] args) {
Animal animal = new Animal();
Animal hAnimal = new Human();
Animal tAnimal = new Tiger();
Human human = new Animal(); //오류발생
}
}
Human과 Tiger는 Animal을 상속받고 있다.
메인에서보면 상위클래스인 Animal 타입으로 하위클래스인 Human과 Tiger를 참조할 수 있도록 하고 있다.
제일 처음에는 Animal타입으로 Animal을 참조하니까 당연히 가능하고
두번째와 세번째는 상위클래스타입으로 하위클래스를 참조하기 때문에 가능하다.
하지만 마지막의 경우는 하위클래스 타입으로 상위클래스를 참조하기 때문에 오류가 발생하는것인데
코드를 보면 하위클래스인 Human은 move(), readBooks() 두개의 메서드를 갖고 있지만
Animal은 move()하나만을 갖고 있다.
그럼 Human타입이면 move와 readBooks를 참조할 수 있어야 한다는 건데 Animal에서 readBooks를 찾을 수 없기
때문에 참조할 수 없게 되는 것이다.
그리고 hAnimal의 경우 Animal타입으로 참조하기 때문에 move만을 사용할 수 있게 된다.
readBooks를 사용하는 경우 ((Human) hAnimal).readBooks(); 이렇게 사용하거나
Human human = (Human)hAnimal;
human.readBooks();
이렇게 다운캐스팅 해서 사용할 수 있다.
만약 hAnimal을
Tiger human = (Tiger)hAnimal;
human.hunting();
이렇게 캐스팅을 하게되면 실행하기 전에는 오류가 발생하지 않지만 실행하게 되면
ClassCastException이 발생한다. Human에 대한 인스턴스인데 Tiger로 강제 캐스팅을 하려고 했기 때문에
에러가 나는 것이다.
instanceof
다형성으로 인해 런타임에 참조변수가 실제로 참조하고 있는 인스턴스의 타입을 확인할 필요성이 생긴다.
instanceof는 참조변수가 참조하고 있는 인스턴스의 실제 타입을 확인할 수 있도록 해준다.
public class AnimalTest {
public static void main(String[] args) {
Animal animal = new Animal();
Animal hAnimal = new Human();
Animal tAnimal = new Tiger();
if(hAnimal instanceof Tiger){
Tiger human = (Tiger)hAnimal;
human.hunting();
}else if(hAnimal instanceof Human){
Human human = (Human)hAnimal;
human.readBooks();
}else{
System.out.println("Error!");
}
}
}
위 코드에서 보자면 hAnimal의 인스턴스가 Tiger라면 이라는 조건문이다.
hAnimal의 인스턴스는 Human이므로 false를 반환한다.
예제는 다 직접 작성했지만 매개변수로 넘어왔다거나 한다면 잘못넘어오는 경우가 있을 수 있다.
이렇게 instanceof를 활용하면 조건에 따라 처리할 수 있으므로 ClassCastException을 피해 실행할 수 있다.
예제코드
import java.util.ArrayList;
class Animal{
public void move(){
System.out.println("동물이 움직입니다.");
}
}
class Human extends Animal{
public void move(){
System.out.println("사람이 걷습니다.");
}
public void readBooks(){
System.out.println("사람이 책을 읽습니다.");
}
}
class Tiger extends Animal{
public void move(){
System.out.println("호랑이가 네발로 뜁니다.");
}
public void hunting(){
System.out.println("호랑이가 사냥을 합니다.");
}
}
class Eagle extends Animal{
public void move(){
System.out.println("독수리가 날아갑니다.");
}
public void flying(){
System.out.println("독수리가 멀리 날아갑니다.");
}
}
public class AnimalTest {
public static void main(String[] args) {
Animal hAnimal = new Human();
Animal tAnimal = new Tiger();
Animal eAnimal = new Eagle();
ArrayList<Animal> animalList = new ArrayList<Animal>();
animalList.add(hAnimal);
animalList.add(tAnimal);
animalList.add(eAnimal);
AnimalTest test = new AnimalTest();
test.testDownCasting(animalList);
System.out.println("-------------------------------");
for(Animal animal : animalList){
animal.move();
}
}//main end
public void testDownCasting(ArrayList<Animal> list){
for(int i = 0; i < list.size(); i++){
Animal ani = list.get(i);
if(ani instanceof Human){
Human human = (Human)ani;
human.readBooks();
}else if(ani instanceof Tiger){
Tiger tiger = (Tiger)ani;
tiger.hunting();
}else if(ani instanceof Eagle){
Eagle eagle = (Eagle)ani;
eagle.flying();
}else{
System.out.println("Error!");
}
}//for end
}//testDownCasting end
}
결과값
사람이 책을 읽습니다.
호랑이가 사냥을 합니다.
독수리가 멀리 날아갑니다.
-------------------------------
사람이 걷습니다.
호랑이가 네발로 뜁니다.
독수리가 날아갑니다.
레퍼런스
● 패스트캠퍼스 올인원 패키지 - 자바 객체지향프로그래밍
'JAVA' 카테고리의 다른 글
인터페이스(Interface) (0) | 2021.01.31 |
---|---|
생성자(Constructor) (0) | 2021.01.30 |
상속(inheritance) (0) | 2021.01.28 |
캡슐화(Encapsulation) (0) | 2021.01.27 |
추상화(Abstraction) (0) | 2021.01.27 |