이 글은 패스트 캠퍼스 한번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 강의를 듣고 공부한 내용을 바탕으로 정리한 글입니다.
1. 다형성
다형성(polymorphism)이란 '여러 개의 형태를 갖는다'라는 의미입니다. 즉, 하나의 코드가 여러 자료형으로 구현되어 실행되는 것을 말합니다. 따라서 같은 코드에서 자료형에 따라 다른 실행 결과가 나옵니다.
이는 정보 은닉과 상속과 함께 객체지향 프로그래밍의 가장 큰 특징 중 하나이자 장점입니다. 다형성을 잘 활용하면 유연하고, 확장성있고, 유지보수가 편리한 프로그램을 만들 수 있습니다.
예시로 동물 클래스를 상속받는 인간, 호랑이, 독수리 클래스를 만들어보겠습니다.
class Animal {
public void move() {
System.out.println("동물이 움직입니다.");
}
}
class Human extends Animal {
@Override
public void move() {
System.out.println("사람이 움직입니다.");
}
public void read() {
System.out.println("사람이 책을 읽습니다.");
}
}
class Tiger extends Animal {
@Override
public void move() {
System.out.println("호랑이가 움직입니다.");
}
public void hunt() {
System.out.println("호랑이가 사냥을 합니다.");
}
}
class Eagle extends Animal {
@Override
public void move() {
System.out.println("독수리가 움직입니다.");
}
public void fly() {
System.out.println("독수리가 하늘을 납니다.");
}
}
위 코드에서는 모든 동물의 공통된 특징인 move()
메서드를 상위 클래스인 Animal
에 정의해주었고, Amimal
을 상속받는 Human
, Tiger
, Eagle
클래스를 작성하였습니다. Human
, Tiger
, Eager
클래스는 move()
메서드를 오버라이딩해주었고, 각각의 고유한 특징(read()
, hunt()
, fly()
)을 메서드로 작성해주었습니다.
그리고 메인 함수에서 Animal로 업캐스팅된 객체들의 move() 메서드를 호출시켜보겠습니다.
public class AnimalTest {
public static void main(String[] args) {
Animal hAnimal = new Human();
Animal tAnimal = new Tiger();
Animal eAnimal = new Eagle();
AnimalTest test = new AnimalTest();
test.moveAnimal(hAnimal);
test.moveAnimal(tAnimal);
test.moveAnimal(eAnimal);
ArrayList<Animal> animalArrayList = new ArrayList<>();
animalArrayList.add(hAnimal);
animalArrayList.add(tAnimal);
animalArrayList.add(eAnimal);
for (Animal animal : animalArrayList) {
System.out.println(animal);
animal.move();
}
}
public void moveAnimal(Animal animal) {
animal.move();
}
}
hAnimal
, tAnimal
, eAnimal
은 모두 Human()
, Tiger()
, Eagle()
생성자로 생성되었지만 타입은 Animal
입니다. AnimalTest
클래스에 moveAnimal()
메서드는 파라미터로 Animal
타입을 받는데, hAnimal
, tAnimal
, eAnimal
의 타입은 Animal
로 업캐스팅되었으므로 당연히 넣을 수 있습니다. 마찬가지로 Animal
타입의 배열에도 넣을 수 있죠! 그 후, 각 객체의 move()
메서드를 호출해보면 가상 메서드의 원리에 의해 각각 오버라이딩된 메서드가 호출됩니다. 아래 실행 결과로 확인할 수 있습니다.
같은 메서드인 moveAnimal()
이 각각 다른 결과를 출력하고, for문 안에서도 같은 move()
메서드를 호출했는데도, 모두 다른 실행 결과가 나타났습니다. 이것이 바로 다형성입니다. 같은 코드임에도 불구하고 객체의 타입에 따라 다른 실행결과가 나타나는 것이죠!
상속을 함으로써 하위 클래스들을 하나의 상위 클래스 타입으로 모두 핸들링할 수 있습니다. (다만 결합도가 높아지는 것은 주의해야 합니다. - 상위 클래스가 바뀌면 하위 클래스가 모두 바뀝니다!)
2. 다형성을 사용하는 이유
- 확장성 있는 프로그램, 유지보수가 쉬운 프로그램을 만들기 위해서
상속과 메서드 오버라이딩을 활용하여 확장성있는 프로그램을 만들 수 있습니다. 위의 예시에서 상속을 사용하지 않으면 많은 메서드에 if-else 구문이 들어가야 합니다. 그런데 여기서 다른 동물을 추가한다면 어떻게 될까요? 그 메서드에 하나하나 조건 분기를 하나 더 넣어주어야 하겠지요...(아래 처럼요!)
class Animal {
public String animalType;
public Animal(String animalType) {
this.animalType = animalType;
}
public void move() {
if (animalType == "human") {
System.out.println("사람이 움직입니다.");
}
else if (animalType == "tiger") {
System.out.println("호랑이가 움직입니다.");
}
...
}
}
- 여러 클래스를 하나의 타입(상위 클래스)에서 한 번에 핸들링 하기 위해서
'Java' 카테고리의 다른 글
[Kotlin] Command-line으로 컴파일하고 실행하기 (0) | 2023.03.09 |
---|---|
[JAVA 객체지향프로그래밍] 인터페이스 (인터페이스를 사용하는 이유, 템플릿 메서드, DAO 구현) (0) | 2023.01.09 |
[JAVA 객체지향프로그래밍] 오버라이딩과 가상메서드 (0) | 2022.12.29 |
[JAVA 객체지향프로그래밍] 상속 (0) | 2022.12.27 |
[JAVA 객체지향프로그래밍] static과 싱글톤 패턴 (0) | 2022.12.23 |
댓글