[JAVA] 다형성

안요한·2022년 5월 19일
0

JAVA

목록 보기
10/16
post-custom-banner

5.1 다형성이란?

💡 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다는 것.
CaptionTv c = new CaptionTv();
Tc        t = new CaptionTv();

//둘 다 같은 타입의 인스턴스지만 참조변수 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다.
//참조변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버 개수보다 같거나 적어야 한다.

조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있다.

반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.

5.2 참조변수의 형변환

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

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

class CastingTest1 {
	public static void main(String args[]) {
		Car car = null;
		FireEngine fe = new FireEngine();
		FireEngine fe2 = null;

		fe.water();
		car = fe;     // car = (Car)fe;에서 형변환이 생략된 형태다.
//	car.water();	// 컴파일 에러!!! Car타입의 참조변수로는 water()를 호출할 수 없다.
		fe2 = (FireEngine)car; 
		fe2.water();
	}
}

class Car {
	String color;
	int door;

	void drive() { 		// 운전기능
		System.out.println("drive, Brrrr~");
	}

	void stop() {			//멈추는 기능
		System.out.println("stop!!!");	
	}
}

class FireEngine extends Car {	//소방차
	void water() {		// 물뿌림
		System.out.println("water!!!");
	}
}
  1. Car car = null;

→ Car타입의 참조변수 car를 선언하고 null로 초기화.

  1. FireEngine fe = new FireEngine();

→ FireEngine 인스턴스를 생성하고 FireEngine타입의 참조변수가 참조하도록 한다.

  1. car = fe; // 조상 타입 ← 자손 타입

→ 참조변수 fe가 참조하고 있는 인스턴스를 참조변수 car가 참조하도록 한다. fe의 값(fe가 참조하고 있는 인스턴스의 주소)이 car에 저장된다. 이 때 형변환은 생략.

이제는 car를 통해서도 FireEngine인스턴스를 사용할 수 있지만, fe와 달리 car는 Car타입이므로 Car클래스의 멤버가 아닌 water()는 사용할 수 없다.

  1. fe2 = (FireEngine)car; // 자손 타입 ← 조상 타입

→ car가 참조하고 있는 인스턴스를 fe2가 참조하도록 한다.

이 때 형변환 해줘야함.

car와는 달리 fe2는 FireEngine타입이므로 FireEngine인스턴스의 모든 멤버들을 사용할 수 있다.

💡 서로 상속관계에 있는 타입간의 형변환은 양방향으로 자유롭게 수행될 수 있으나, **참조변수가 가리키는 인스턴스의 자손타입으로 형변환은 허용되지 않는다. 그래서 참조변수가 가리키는 인스턴스의 타입이 무엇인지 확인하는 것이 중요하다.**

5.3 instanceof 연산자

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

왼쪽에는 참조변수를 오른쪽에는 타입(클래스명)이 피연산자로 위치.

💡 어떤 타입에 대한 instanceof연산의 결과가 true라는 것은 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.

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

멤버변수가 조상 클래스와 자손 클래스에 중복으로 정의된 경우, 조상타입의 참조변수를 사용했을 때는 조상 클래스에 선언된 멤버변수가 사용되고, 자손타입의 참조변수를 사용했을 때는 자손 클래스에 선언된 멤버변수가 사용된다.

5.5 매개변수의 다형성

  • 예제 7-21/PolyArgumentTest.java
class Product {
	int price;			//제품의 가격
	int bonusPoint;	//제품구매 시 제공되는 보너스점수	

	Product(int price) {
		this.price = price;
		bonusPoint =(int)(price/10.0);	// 보너스점수는 제품가격의 10%
	}
}

class Tv3 extends Product {
	Tv3() {
		// 조상클래스의 생성자 Product(int price)를 호출한다.
		super(100);			//Tv의 가격을 100만원으로 한다.
	}
	// Object클래스의 toString()을 오버라이딩 한다.
	public String toString() {	
		return "Tv";
	}
}

class Computer extends Product {
	Computer() {
		super(200);
	}

	public String toString() {
		return "Computer";
	}
}

class Buyer {			   //고객, 물건을 사는 사람
	int money = 1000;	 //소유금액
	int bonusPoint = 0;//보너스점수	

	void buy(Product p) {
		if(money < p.price) {
			System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
			return;
		}

		money -= p.price;			      // 가진 돈에서 구입한 제품의 가격을 뺀다.
		bonusPoint += p.bonusPoint;	// 제품의 보너스 점수를 추가한다.
		System.out.println(p + "을/를 구입하셨습니다.");
	}
}

class PolyArgumentTest {
	public static void main(String args[]) {
		Buyer b = new Buyer();

		b.buy(new Tv3());
		b.buy(new Computer());

		System.out.println("현재 남은 돈은 " + b.money + "만원입니다.");
		System.out.println("현재 보너스 점수는 " + b.bonusPoint + "점입니다.");
	}
}

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

  • 예제 7-22/PolyArgumentTest2.java
class Buyer2 {			
	int money = 1000;	
	int bonusPoint = 0;	
	**Product2[] item = new Product2[10];**	
	int i =0;			

	void buy(**Product2 p**) {
		if(money < p.price) {
			System.out.println("잔액이 부족하여 물건을 살 수 없습니다.");
			return;
		}

		money -= p.price;	        
		bonusPoint += p.bonusPoint;	
		**item[i++] = p;**		        
		System.out.println(p + "을/를 구입하셨습니다.");
	}
}

/*구입한 제품을 담기 위해 Buyer클래스에 Product배열인 item을 추가해주었다.
그리고 buy메서드에 'item[i++] = p;' 문장르 추가함으로써 물건을 구입하면, 배열 item에 저장되도록 했다.
이렇게 함으로써, 모든 제품클래스의 조상인 Product클래스 타입의 배열을 사용함으로써 
구입한 제품을 하나의 배열로 간단하게 다룰 수 있게 된다.
*/
profile
걍이렇게돼브렀다리
post-custom-banner

0개의 댓글