끄적모음
객체지향 PART 4 - 다형성
taehyon
2025. 4. 15. 20:37
다형성(Polymorphism)이란?
- 다형성은 하나의 타입으로 여러 객체를 다룰 수 있는 객체지향의 4번째 특징입니다.
- 인터페이스 상속, 클래스 상속을 활용해서 추상계층을 표현해 왔습니다.
- 이제 추상 계층이라는 특징을 활용해서 다형성을 구현할 수 있습니다.
인터페이스를 활용한 다형성
public interface LifeForm {
void exist();
}
public interface Animal extends LifeForm {
void makeSound();
}
public class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("야옹");
}
@Override
public void exist() {
System.out.println("고양이가 존재합니다.");
}
public void scratch() {
System.out.println("스크래치!");
}
}
public class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("멍멍");
}
@Override
public void exist() {
System.out.println("강아지가 존재합니다.");
}
public void wag() {
System.out.println("꼬리 흔들");
}
}
public class Main {
public static void main(String[] args) {
// 다형성 활용
Animal animal = new Cat();
animal.exist(); // ✅
animal.makeSound(); // ✅
}
}
형변환(Casting)
형변환이 다형성에서 중요한 이유를 알아봅시다.
- 부모타입으로 자식타입을 다룰 수 있는 이유는 자동으로 형변환(Casting) 이 발생했기 때문입니다.
- 자식타입 → 부모타입: 업캐스팅(UpCasting)
- 부모타입 → 자식타입: 다운캐스팅(DownCasting)
업캐스팅(UpCasting) - 자식 → 부모
- 부모타입으로 자식타입을 다룰 수 있는 이유는 업캐스팅(UpCasting) 때문입니다.
public class Main {
public static void main(String[] args) {
// 다형성 활용
Animal animal = new Cat(); // ✅ 자동 형 변환
animal.exist(); // ✅
animal.makeSound(); // ✅
}
}
업캐스팅(UpCasting)의 주의사항
업캐스팅은 부모의 타입으로 데이터를 다룰 수 있지만 자식 클래스의 고유기능을 활용할 수 없습니다.
- 자식 클래스의 고유 기능을 사용하려면 다운캐스팅 이 필요합니다.
public class Main {
public static void main(String[] args) {
// 다형성 활용
Animal animal = new Cat(); // ✅ 자동 형 변환
animal.exist();
animal.makeSound();
animal.scratch(); // ❌ 사용 불가
}
}
다운캐스팅(DownCasting):
- 부모 → 자식 다운캐스팅으로 자식 클래스의 고유 메서드를 사용할 수 있습니다.
public class Main {
public static void main(String[] args) {
// 다형성 활용
Animal animal = new Cat();
animal.exist();
animal.makeSound();
Cat cat = (Cat) animal; // ✅ 다운캐스팅(부모Animal -> 자식Cat)
cat.scratch(); // ✅ 자식 클래스의 기능 활용 가능
}
}
다운캐스팅(DownCasting)의 주의사항
잘못된 다운캐스팅은 컴파일단계에서 감지할 수 없습니다.
- 컴파일러는 다운캐스팅이 문법적으로 올바른지 여부만 검사해주기 때문에
- 런타임시에 실제 어떤 객체가 변수에 할당되는지 검사해 주지 않습니다.
- 컴파일 시점에는 오류 없이 통과되지만 런타임시점에 ClassCastException 이 발생할 가능성이 있습니다.
public class Main {
public static void main(String[] args) {
// 다운 캐스팅
Animal dog = new Dog();
// 문법적으로 잘못된건 아니라서 에러가 발생하지 않습니다.
Cat cat1 = (Cat) dog; // ⚠️
cat1.scratch(); // ❌ 해당 라인이 실행할때만 에러 여부를 확인할 수 있습니다.
}
}
그래서 다운캐스팅을 사용할때 항상 instanceof 를 활용해야합니다.
- instanceof 는 객체가 특정 클래스나 인터페이스의 인스턴스인지 확인해 주는 역할을 합니다.
- 주로 다운캐스팅 하기 전에 타입을 검사해서 ClassCastException 을 예방하는데 활용됩니다.
public class Main {
public static void main(String[] args) {
Animal animal2 = new Dog();
// ✅ 안전한 다운캐스팅(animal2 가 Cat 의 인스턴스 유형인지 확인합니다.)
if (animal2 instanceof Cat) {
Cat cat = (Cat) animal2;
cat.scratch();
} else {
System.out.println("객체가 고양이가 아닙니다.");
}
}
}
다형성의 장점 맛보기
public class Main {
public static void main(String[] args) {
Animal[] animals = {new Cat(), new Dog()};
for (Animal animal : animals) {
animal.makeSound();
}
}
}