///////
Search

13_다형성_곽철민

다형성

같은 이름의 메소드가 클래스 혹은 객체에 따라 다르게 동작하도록 구현되는 것
다형성에는 오버라이딩과 오버로딩이 있습니다.
오버라이딩(Overriding)
슈퍼 클래스의 메소드를 서브 클래스에서 자신의 상황에 맞게 재정의하는 것
오버로딩(Overloadding)
같은 클래스 내부 혹은 상속 관계에 있는 클래스에서 메소드 이름은 같지만 매개변수의 타입과 개수가 다른 메소드들을 여러개 만드는 것
그렇다면 이러한 다형성의 개념이 왜 활용되는 것일까요? 예제를 통해 이해해봅시다.
동물을 나타내는 Animal 클래스
package java_0926; public class Animal{ public void talk(){ System.out.println("동물이 말을 합니다."); } }
Java
복사
Animal 클래스를 상속받은 Cat 클래스
package java_0926; public class Cat extends Animal{ @Override public void talk(){ System.out.println("야옹"); } }
Java
복사
Animal 클래스를 상속받은 Dog 클래스
package java_0926; public class Dog extends Animal { @Override public void talk(){ System.out.println("멍멍멍"); } }
Java
복사
package java_0926; public class Main { public static void main(String[] args) { Animal cat = new Cat(); Animal dog = new Dog(); cat.talk() dog.talk(); } }
Java
복사
[출력 결과]
위의 예제는 Animal 클래스를 상속받은 Cat 클래스와, Dog 클래스를 나타냅니다.
동물은 서로 말하는 방식이 다른 것을 실생활에서 볼 수 있습니다.
이는 다형성으로 표현해낼 수 있습니다.
서브 클래스는 슈퍼 클래스로 부터 상속받은 메소드(talk())를 그들의 상황에 맞게 재정의합니다.
이를 우리는 오버라이딩(Overriding)이라고 부릅니다.
따라서, 출력 결과는 “야옹”과 “멍멍멍” 으로 나타나는 것을 볼 수 있습니다.

업캐스팅과 다운 캐스팅

업캐스팅
서브 클래스의 객체에 대한 레퍼런스를 슈퍼 클래스 타입으로 변환하는 것
class Person{ ... } class Student extends Person{ ... } class Researcher extends Person{ ... } class Professor extends Researcher{ ... }
Java
복사
Person p = new Student();
Java
복사
자바에서 서브 클래스는 슈퍼 클래스의 멤버를 상속 받기 때문에, 서브 클래스 객체는 슈퍼 클래스 멤버를 모두 갖습니다.
따라서, 서브 클래스 객체를 슈퍼 클래스가 가리킬 수 있는 것 입니다.
다만, 슈퍼 클래스의 레퍼런스로 서브 클래스의 멤버에 접근하지 못합니다.
슈퍼 클래스의 레퍼런스로는 슈퍼 클래스의 멤버에만 접근할 수 있습니다.
다운캐스팅
슈퍼 클래스 타입의 객체를 서브 클래스 타입의 레퍼런스로 가리키는 것
다형성 적용으로 잃어버린 특성을 복구 시키기 위해 원래 상태로 되돌리는 것
업캐스팅과 달리 명시적으로 타입 변환을 지정해주어야 합니다.
Person p = new Student(); Student s = (Student) p //다운 캐스팅
Java
복사

instanceof 연산자

슈퍼 클래스를 상속받은 서브 클래스가 여러개 존재하는 경우, 슈퍼 클래스의 레퍼런스가 가리키는 객체의 진짜 클래스 타입을 구분하는 데에는 어려움이 있습니다.
예제를 통해 알아봅시다.
Person p = new Person(); Person p = new Student(); Person p = new Researcher(); Person p = new Professor();
Java
복사
print(p); // Person 타입의 레퍼런스 p가 어떤 타입의 객체를 가리키는지 알 수 없음 public void print(Person person){ //person이 가리키는 객체가 Person 타입이 될 수도, //Student, Researcher, Professor가 될수도 있다. }
Java
복사
슈퍼 클래스인 Person, 서브 클래스인 Student,Researcher, Professor가 존재합니다.
이 때, print() 메소드의 파라미터에는 Person 타입의 객체를 전달받습니다.
print() 메소드가 오직 아는 것은 Person 객체를 상속받은 객체가 업캐스팅 되어 넘어왔거나 혹은 Person 객체가 넘어왔다는 것입니다.
이 때, instanceof 연산자를 이용하면 레퍼런스가 가리키는 객체가 어떤 클래스 타입인지 구분할 수 있습니다.
instanceof 연산자 표기법
레퍼런스명 instanceof 클래스타입
public void print(person person){ if(person instanceof Student){ System.out.println("파라미터로 넘어오는 개체의 타입은 Student 타입입니다.") } }
Java
복사
boolean 타입으로, 레퍼런스가 가리키는 객체가 해당 클래스 타입의 객체이면 true이고 아니면 false로 계산됩니다.
instanceof는 클래스에만 적용됩니다.(클래스 타입을 작성하는 부분에 Primitive 타입 X)
다음과 같이 instanceof 연산자를 통해, 레퍼런스가 어떤 클래스 타입인지 알 수 있습니다.