해당 포스팅은 한빛 미디어의
혼자 공부하는 자바
와
유튜브Yalco
님의 강의를 바탕으로 작성했습니다.
다형성(Polymorphism)
이란 하나의 타입에 여러가지 타입의 데이터를 대입하여
다양한 결과를 얻어낼 수 있는 성질을 의미한다.
이를 통해 하나의 객체는 여러가지 형태를 가질 수 있다.
상위 클래스의 참조 변수로 하위 클래스의 참조 변수를 다루거나(Upcasting
)
동일한 이름의 메소드를 여러 형태(Override
)로 만들 수 있다.
즉, 다형성은 클래스가 상속관계가 있을 때 나타나는 다채로운 성질이다.
자바에선 대표적으로 아래의 방법들이 다형성에 속한다.
오버로딩(Overloading)
오버라이딩(Overriding)
업캐스팅(Upcasting)
✅다운캐스팅(Downcasting)
✅인터페이스(Interface)
추상메소드(Abstract Method)
추상클래스(Abstract Class)
클래스 타입 변환은 상속 관계에 있는 클래스들 사이에서 객체를 다른 타입으로 변환하는 것이다.
자바에서는 주로 업캐스팅(Upcasting)
과 다운캐스팅(Downcasting)
을 사용한다.
업캐스팅(Upcasting)은 자식 클래스의 객체를 부모 클래스 타입으로 변환하는 것이다.
자바에서 업캐스팅은 자동으로 수행되며, 특별한 연산자나 메서드 호출이 필요하지 않다.
업캐스팅을 통해 부모 클래스 타입의 참조 변수로 자식 클래스의 객체를 다룰 수 있다.
// Animal.java
public class Animal{
public void makeSound(){
System.out.println("Animal makes a sound");
}
}
// Dog.java
public class Dog extends Animal{
@Override
public void makeSound(){
System.out.println("Bow-Wow");
}
public void favSnack(){
System.out.println("Beef Jerky");
}
}
// Main.java
public class Main{
public static void main(String[] args){
Dog dog = new Dog();
Animal animal = dog; // 업캐스팅
// 또는 Animal animal = new Dog();
animal.makeSound(); // "Bow-Wow"
animal.favSnack(); // ❌Error
}
}
dog
을 부모 클래스 Animal
타입으로 캐스팅(업캐스팅)다운캐스팅(Downcasting)은 부모 클래스 타입을 자식 클래스 타입으로 변환하는 것이다.
다운캐스팅은 명시적으로 변환해야 하며, 타입 캐스팅 연산자를 사용한다.
더 명확하게 말하면, 부모 클래스 타입으로 자식 객체를 참조하던 참조변수의 타입을
다시 자식 클래스 타입으로 변환하는 것이다.
다운캐스팅은 단순히 업캐스팅의 반대 개념이 아니다.
다운캐스팅의 진정한 의미는 부모 클래스로 업캐스팅된 자식 클래스를 복구하여
본인의 필드와 기능을 회복하기 위해 있는 것이다.
💡 다운캐스팅을 하기 위한 사전 조건은 업캐스팅이 먼저 이루어진 경우다.
Parnet parent = new Child(); // 업캐스팅
Child child = (Child) parent; // 다운 캐스팅
// Animal.java
public class Animal{
public void makeSound(){
System.out.println("Animal makes a sound");
}
}
// Dog.java
public class Dog extends Animal{
@Override
public void makeSound(){
System.out.println("Bow-Wow");
}
public void favSnack(){
System.out.println("Beef Jerky");
}
}
// Main.java
public class Main{
public static void main(String[] args){
Animal animal = new Dog(); // 업캐스팅
animal.makeSound(); // "Bow-Wow"
animal.favSnack(); // ❌Error
if(animal instanceof Dog{ // 다운 캐스팅
Dog dog = (Dog) animal;
dog.favSnack(); // ✅Success
}
}
instanceof
연산자다운캐스팅(강제 타입 변환)은 자식 타입이 부모 타입으로 변환되어 있는 상태(업캐스팅)에서만 가능하기에 처음부터 부모타입으로 생성된 객체는 자식 타입으로 변환할 수 없다
Parent parent = new Parent();
Child child = (Child) parent; // ❌Error
따라서 부모 변수가 참조하는 객체가 부모 객체인지, 자식 객체인지 확인이 먼저 필요하다.
instanceof
연산자는 뒤에 오는 클래스의 자료형에 속하는 인지턴스인지 확인하고
boolean타입(true/false)를 반환한다.
다운캐스팅에서 instanceof
를 사용하는 이유는,
해당 객체가 실제로 하위 클래스의 인스턴스인지 확인하기 위해서이다.
이를 통해 ClassCastException
같은 런타임 에러를 방지할 수 있다.
// parent가 Child의 인스턴지인지 확인
if(parent instanceof Child){
Child child = (Child) parent;
}
자식 클래스의 인스턴스는 모두 부모 클래스의 자료형에 속하므로
부모 클래스의 범주로 묶어 배열에서 사용 가능하다. - 타입 묶음
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
class Hamster extends Animal{
}
Animal[] animals = {
new Animal(),
new Dog(),
new Cat()
};
업캐스팅과 다운캐스팅 과정에서 animal
과 dog
은 모두 같은 Dog
객체를 참조한다.
Dog
객체를 참조하는 타입의 차이만 있을 뿐, 참조 대상 객체는 동일하다.
animal
은 Animal
타입으로 참조한다.dog
은 Dog
타입으로 참조한다.객체를 참조하는 타입의 차이로 인해 접근할 수 있는 필드와 메서드가 다를 수 있다.
animal
을 통해 호출할 수 있는 메소드는 Animal
클래스에서 정의된 메서드dog
을 통해 호출할 수 있는 메소드는 Dog
클래스에서 정의된 메서드Object
클래스는 Java에서 모든 클래스의 최상위 부모 클래스다.
모든 클래스는 암묵적으로 Object
클래스를 상속받는다.
모두의 조상, 모든 자료형을 다룰 수 있다.
Object
클래스에서 정의된 메소드를 사용할 수 있다.toString()
- 객체를 문자열로 변환equals(Object obj)
- 두 객체의 동등성 비교hashCode()
- 객체의 해시 코드 반환getClass()
- 객체의 런타임 클래스 반환clone()
- 객체의 복제본 반환notify
, notifyAll()
, wait()
- 스레드 동기화 관련 메소드Object
클래스의 메서드는 서브클래스에서 오버라이드해 다양한 구현을 제공한다.