20150916


다형성(polymorphism)


다형성을 알기 위해서는 상속에 대한 개념을 알고 있어야 합니다.

우선 자바에서 다형성은 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있게 하므로써 다형성을 나타냅니다.

즉 '여러 가지 형태를 가질 수 있는 능력' 을 의미합니다.

그러니깐 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조 할 수 있도록 한 겁니다.


car 클래스와 car 클래스를 상속받는 SuperCar 클래스로 예를 들면

아래 코드와 같이 


class Car {

	int speed = 10;
	void speedUp(){
		++speed;
		System.out.println("car 에서 speed:" + speed + "입니다.");
	}
}

class SuperCar extends Car {

	int speed = 9;
	int model = 2;
	boolean booster = false;
	void speedUp(){
		speed += 2;
		System.out.println("supercar에서 speed:" + speed +  "입니다.");
	}
}

class Test2 {
	public static void main(String[] args) {

		Car c = new Car();
		SuperCar sc = new SuperCar();
		Car c2 = new SuperCar();
		
		System.out.println(sc.model); //2   출력됨
	//	System.out.println(c2.model); // 오류남 변수 model를 사용 할 수 없다.

        System.out.println(c.speed);  //10 이 출력됨
		System.out.println(sc.speed); // 9 가 출력됨
		
		c.speedUp();  //car 에서 speed:11입니다. 가 출렴됨
		c2.speedUp(); //supercar에서 speed:12입니다. 가 출력됨
	}
}

Car 클래스 와  SuperCar 클래스 두 클래스의 인스턴스를 생성하고 사용하기 위해서 24번 25번 줄처럼 Car c = new Car(); 이런식으로 인스턴스 타입과 참조변수의 타입을 일치해서 사용하는건 아시죠? 그런데 여기서 Car 클래스와 SuperCar 클래스 처럼 서로 상속 관계는 Car c = new SuperCar(); 이런식으로 참조가 가능합니다.

그럼 Car c = new Car(); 와 Car c = new SuperCar(); 의 차이를 설명하자면

왼쪽의 참조변수 타입이 가지고 있는 맴버 변수만 사용이 가능합니다. 쉽게 말해서

car 클래스 맴버의 수는 2가지를 가지고 있고 CarSuperCar클래스는 상속받은 2개 와 자신이 가지고 있는 int model, boolean booster 를 총 더한 4가지고 가지고 있습니다.

Car c = new SuperCar(); 를 예를 들면 참조변수가 c 는 Car 클래스가 가지고 있는 맴버변수 2개만 사용 가능합니다. 그래서 car 는 가지고 있지 못한 SuperCar 의 변수는 사용을 할 수 없습니다.

25번 26번 줄에서 같은 인스턴스로 만들었지만 다른 참조변수 인 scc228번29번 줄에서 출력해보면 29번 줄은 참조변수 타입이 Car 라서 SuperCar 가 가지고 있는 model 변수를 사용 할 수 없어요. (오류가 납니다.)

그리고 25번26번 차이처럼 같은 부모클래스와 자식클래스가 둘다 가지고 있는 맴버변수는 참조변수 클래스에 있는 변수를 사용합니다.

하지만 31번32번 차이처럼 같은 부모클래스와 자식클래스가 둘다 가지고 있는 맴버함수는 좀 더 구체화(오버 라이딩)된 자식클래스의 함수를 사용합니다.


반대로 SuperCar sc = new Car(); 는 사용 할 수 없습니다.

위에서 설명 했듯이 참조변수의 타입 맴버 수 만 사용 할 수 있다고 했는데 이런 경우가 되면 사용 할 수 있는 범위중에서 사용 못하는 멤버가 들어가기 때문에 오류가 납니다.

예) sc.model  참조변수 타입 맴버에는 model 변수도 사용 가능 해야 하지만 인스턴스인 car 에는 model 변수가 없기 때문입니다.  

참조변수가 사용할 수 있는 맴버 수 는 인스턴스의 개수보다 같거나 작아야 합니다.






참조변수의 형변환


서로 상속관계인 클래스 사이에서는 참조변수도 형변환이 가능합니다.

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

아래 코드에서 처럼
class Car {
.....
}

class SuperCar extends Car {
....
}

class Test2 {
	public static void main(String[] args) {

		Car c = new Car();
		SuperCar sc = new SuperCar();
	
c = sc; //형변환 생략가능 
sc = (SuperCar)c;  //형변환 생략할 수 없다.		
	}
}

아래 코드에서 와 같이 car 와 SuperCar 처럼 상속 관계에서는 15번 줄처럼 형변환이 가능하다. 형변환을 하면 인스턴스의 멤버중 사용 할 수 있는 범위가 달라지게 됩니다.
sc 의 참조변수 타입이 SuperCar 라서 superCar 클래스의 변수를 모두 사용 가능한데 c 참조 변수로 형변환을 하게 되면 Car 클래스가 가지고 있는 변수들만 사용 가능합니다.  

참조변수 형변환은 참조변수의 타입이 변환되는 것이기 때문에 인스턴스는 변하지 않습니다.




+ Recent posts