[java] 다형성

다형성(polymorphism)

- 객체지향개념에서의 다형성이란 '여러 가지 형태를 가질 수 있는 능력'을 의미하며, 자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함으로써 다형성을 프로그램적으로 구현하였다. 즉, 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다.

- 둘 다 같은 타입의 인스턴스지만 참조변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다. 즉, 자손타입의 참조변수로 조상타입의 인스턴스를 참조하는 것은 존재하지 않는 멤버를 사용하고자 할 가능성이 있으므로 허용하지 않는다. 참조변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버 개수보다 적어야 하는 것이다.

 

참조변수의 형변환

- 서로 상속관계에 있는 클래스사이에서만 가능하기 때문에 자손타입의 참조변수를 조상타입의 참조변수로, 조상타입의 참조변수를 자손타입의 참조변수의 형변환만 가능하다.

- 바로 윗 조상이나 자손이 아닌 간접적인 상속관계의 경우에도 형변환이 가능하다. 따라서 모든 참조변수는 모든 클래스의 조상인 Object클래스 타입으로 형변환이 가능하다.

[[정리]]--------------------------------------------------

자손타입 ----> 조상타입 (Up-casting) : 형변환 생략가능

자손타입 <---- 조상타입 (Down-casting) : 형변환 생략불가

----------------------------------------------------------

- 형변환은 참조변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에 참조변수의 형변환은 인스턴스에 아무런 영향을 미치지 않는다. 단지 참조변수의 형변환을 통해서, 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위(개수)를 조절하는 것뿐이다.

- 캐스트연산자를 사용하면 서로 상속관계에 있는 클래스 타입의 참조변수간의 형변환은 양방향으로 자유롭게 수행될 수 있다.

 

instanceof연산자

- 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 instanceof연산자를 사용한다.

[[형식]] 참조변수 instanceof 타입(클래스명) => 결과로 blooean값 반환.

- 실제 인스턴스와 같은 타입의 instanceof연산 이외에 조상타입의 instanceof연산에도 true를 결과로 얻으면 검사한 타입으로의 형변환을 해도 아무런 문제가 없다는 뜻이다.

 

참조변수와 인스턴스의 연결

[[주의]] 조상 클래스에 선언된 멤버변수와 같은 이름의 인스턴스변수를 자손 클래스에 중복으로 정의했을 때, 조상타입의 참조변수로 자손 인스턴스를 참조하는 경우와 자손타입의 참조변수로 자손 인스턴스를 참조하는 경우는 서로 다른 결과를 얻는다.

- 메서드의 경우 조상 클래스의 메서드를 자손의 클래스에서 오버라이딩한 경우에도 참조변수의 타입에 관계없이 항상 실제 인스턴스의 메서드(오버라이딩된 메서드)가 호출되지만, 멤버변수의 경우 참조변수의 타입에 따라 달라진다.(static메서드는 참조변수의 타입에 영향을 받는다.)

 

매개변수의 다형성

ex)------------------------------------------------------------------

class Product{

int price;

Product(int price){

this.price = price;

}

}

 

class TV extends Product{

TV(){

super(100);

}

}

 

class Buy{

void buy(TV tv){ ... }  //TV말고 다른 제품의 buy구현시 일일이 메서드 추가해줘야함

void buy(Product p) { ... }  //Product를 상속받은 제품일 경우 메서드 추가 없이 사용 가능

}

 

main(){

Product tv = new TV();

}--------------------------------------------------------------------

 

여러 종류의 객체를 하나의 배열로 다루기

- 조상타입의 참조변수 배열을 사용하면, 공통의 조상을 가진 서로 다른 종류의 객체를 배열로 묶어서 다룰 수 있다. 또는 묶어서 다루고자하는 객체들의 상속관계를 따져서 가장 가까운 공통조상 클래스 타입의 참조변수 배열을 생성해서 객체들을 저장하면 된다.

+참고) Vector 가변 길이 배열.

+참고) 문자열과 참조변수의 덧셈(결합연산)은 참조변수에 toString()을 호출해서 문자열을 얻어 결합한다.