[Java] 다형성(Polymorphism)
Language/Java

[Java] 다형성(Polymorphism)

1. 다형성

 

다형성 정의

- 객체는 하나인데, 여러 가지 형(타입)을 가질 수 있는 성질

- 상속 관계에서 부모 클래스의 타입으로 자식 클래스 객체를 레퍼런스 할 수 있음

 

// 상속 관계 : SpiderMan -> Person -> Object

SpiderMan sm = new SpiderMan();
Person person = sm;			// 가능
Object obj = sm;			// 가능

Person ps = new Person();
SpiderMan sman = ps;			// 불가능

 

다형성의 예

- 다형성으로 다른 타입의 데이터를 하나의 배열로 관리 가능

Person[] persons = new Person[5];
persons[0] = new Person();
persons[1] = new SpiderMan();

- 부모 클래스의 타입으로 파라미터를 사용하면 객체의 타입에 따라 메서드를 만들 필요가 없어짐

public void println(Object x) {			// Object 타입으로 받았기 때문에 x는 어떤 타입도 가능
    String s = String.valueOf(x);
    synchronized (this) {
    	print(s);
        newLine();
    }
}

 

다형성과 메모리의 관계

- 메모리에 있더라도 참조하는 변수의 타입에 따라 접근할 수 있는 내용이 제한됨

- 앞서, 다형성의 예로 부모 클래스 타입을 사용하면 객체의 타입에 따라 메서드를 만들 필요가 없어지는 등 다형성을 이용한 편리함을 얘기했지만, 이렇게 사용하면 자식 클래스의 메서드를 사용하지 못하게 되어 결국 불편함을 초래합니다. 한 가지 예로, SpiderMan과 Person을 관리의 편의상 Object로 사용하려고 하지만, 이렇게 되면 SpiderMan과 Person의 메서드를 사용하지 못하게 됩니다.

메모리에 올라간 SpiderMan, Person, Object 객체

 

참조형 객체의 형 변환

자식 타입 -> 부모 타입 : 묵시적 케스팅

- 모든 부모 타입의 내용이 자식에게 있으므로 형변환 생략이 가능합니다.

// 묵시적 형변환
Person persons = new Person();
Object obj = persons;

부모 타입 -> 자식 타입 : 명시적 케스팅

- 부모 타입이 자식 타입의 내용을 모두 갖고 있지 않을 수 있으므로 명시적으로 형 변환을 해야 합니다.

- 자식 타입의 내용이 이미 메모리에 올라와 있을 경우 명시적 캐스팅을 해서 자식 타입의 메서드를 사용할 수 있습니다.

- 자식 타입의 내용이 메모리에 없는 경우 형 변환은 문법적으로는 오류가 없으나, 자식 타입의 메서드를 사용할 수 없기 때문에 오류가 발생합니다..

// 명시적 형변환
Person persons = new SpiderMan();
SpiderMan sm = (SpiderMan)persons;

instanceof 연산자

- 메모리에 있는 객체가 어떤 클래스 타입인지 boolean 형식으로 리턴

- 이 연산자를 이용하여 참조형 객체의 타입을 변경하기 전에 메모리에 객체가 올라와 있는지 확인할 수 있습니다.

Person persons = new Person("김철수");

if(p instanceof SpiderMan) {
    SpiderMan sm = (SpiderMan)p;
    sm.fireWeb();
}else {
	System.out.println("스파이더맨 X");
}