자바의 정석 7장 (16일차) -instanceof, 다형성

728x90

instanceof

참조변수의 형변환을 하기 전에 instanceof 함수를 써서 형변환 가능여부 확인 > 가능하면 true 반환

사용이유: 형변환하기전에 형변환 가능여부를 확인할 때

  • 조상 멤버를 상속받을 때 어떤 인스턴스를 받을 지 알 수 없기 때문에 instanceof로 TV가 가르키는 smartTV 인스턴스로 형변환이 가능한지 확인해야 함

아래와 같이 형변환이 가능하면 true값을 반환하고 불가능하면 false값을 반환

		SmartTV smarttv = new SmartTV();
		TV tv = new TV();
		
		System.out.println(smarttv instanceof TV);
		System.out.println(smarttv instanceof SmartTV);
		System.out.println(smarttv instanceof Object);
//		true
//		true
//		true
		
		System.out.println(tv instanceof SmartTV);
//		SmartTV tv2 = new TV(); 와 동일한 코드
//      	SmartTV tv2 = (SmartTV)t로 형변환해주면 가능함
		System.out.println(tv instanceof TV);
		System.out.println(smarttv instanceof Object);
//		false
//		true
//		true

 

 

다형성의 장점 2가지

 

1번

  • 다형적 매개변수
    • 아래의 예시에 class buyer에서 매개변수를 조상의 클래스로 둠으로써 코드의 중복을 피할 수 있다.
    • buy 메서드를 각각의 클래스에 정의하여 개별로 쓸 수도 있지만 코드의 중복 + 간결화 불가라는 단점이 있기 때문에 다형적 매개변수의 장점을 살려 두마리의 토끼를 잡은 격
    • 요약: (1) 매개변수에 조상의 클래스를 지정, (2) 메서드를 하나로 단축

다형성 매개변수 다형성 예시

package Lecture;

public class Polymorphism {
	public static void main(String[] args) {
	buyer b = new buyer();
	b.buy(new americano());
	b.buy(new latte());

	System.out.println(b.money);
	}
}

class machine{
	int price; //제품의 가격
	int mileage; //가격대비 마일리지
	
	public machine(int price) {//자손에게서 받아온 가격
		this.price = price; // 자손 클래스에서 받아온 가격을 가져와 조상의 price에 대입
		this.mileage = price / 10;
	}
}

class americano extends machine{
	
	public americano() {
		super(1200); //조상의 멤버변수를 선언하는 super로 조상 생성자 price에 가격대입
	}
	
	public String toString() {
		return "Americano"; //인스턴스를 호출했을 때 return할 값
	}
}

class latte extends machine{
	public latte() {
		super(2000); //위와 동일한 설명
	}
	
	public String toString(){
		return "Latte";
	}
}

class buyer{
	int money = 10000; //보유한 금액이 1만원일 시
	int mileage;
	
	void buy(machine m) {
//		인스턴스 자체를 조상의 변수로 두어 동일한 메서드를 생성하지 않아도 인스턴스 값만 변경하면 값이 도출될 수 있도록 함
//		이 때 조상의 변수로 둔 이유는 자식 인스턴스로 둘 경우에 각각의 자식 인스턴스는 형변환이 불가능하므로 
//		메서드를 추가로 중복 생성해야함 > 코드의 중복 > 매우 bad
//		따라서 americano나 latte가 아닌 조상, 즉 machine으로 두어야 함
		if(money<m.price) {
			return; //가격이 현재 보유 금액보다 클 경우 보유금액 고대로 return
		}
		else { //아닐경우에는 조상의 price와 mileage 누적빼기, 합 프린트
			money -= m.price;
			mileage += m.mileage;
		}
		System.out.println("구입명: " + m + " 남은 금액: " + money +" 마일리지 금액: " + mileage);
//		프린트를 m 매개변수로 둠으로써 toString 출력하기
	}
}

 

2번

  • 하나의 배열로 여러종류 객체다루기
    • 위의 예시처럼 물건이 별로 없으면 하나씩 쓸 수 있겠지만 10개 이상일 경우 매우 귀찮을 것이 뻔하다.
    • 그러므로 인스턴스의 다형성을 이용하여 공통의 조상을 가진 객체들을 배열로 묶어 관리해야 편하다.

아래는 배열을 만들어서 구매한 목록을 String 문자열로 서로 더해 마지막에 출력한 예제

달라진 코드는 없고 buyer 클래스에 summery 메서드를 추가하여 for 반복문으로 각각의 조상 변수를 array에 저장하고

저장한 이름 값을 카트라는 array 변수에 넣어 마지막에 출력함

 

출력값:

금액 표기 [잔돈=₩ 6,800, 마일리지=320]
구매 목록 Americano Latte 

package Lecture;

public class Polymorphism {
	public static void main(String[] args) {
	buyer b = new buyer();
	b.buy(new americano());
	b.buy(new latte());

	System.out.println(b.money);
	}
}

class machine{
	int price; //제품의 가격
	int mileage; //가격대비 마일리지
	
	public machine(int price) {//자손에게서 받아온 가격
		this.price = price; // 자손 클래스에서 받아온 가격을 가져와 조상의 price에 대입
		this.mileage = price / 10;
	}
}

class americano extends machine{
	
	public americano() {
		super(1200); //조상의 멤버변수를 선언하는 super로 조상 생성자 price에 가격대입
	}
	
	public String toString() {
		return "Americano"; //인스턴스를 호출했을 때 return할 값
	}
}

class latte extends machine{
	public latte() {
		super(2000); //위와 동일한 설명
	}
	
	public String toString(){
		return "Latte";
	}
}

class buyer{
	int money = 10000; //보유한 금액이 1만원일 시
	int mileage;
	
	void buy(machine m) {
//		인스턴스 자체를 조상의 변수로 두어 동일한 메서드를 생성하지 않아도 인스턴스 값만 변경하면 값이 도출될 수 있도록 함
//		이 때 조상의 변수로 둔 이유는 자식 인스턴스로 둘 경우에 각각의 자식 인스턴스는 형변환이 불가능하므로 
//		메서드를 추가로 중복 생성해야함 > 코드의 중복 > 매우 bad
//		따라서 americano나 latte가 아닌 조상, 즉 machine으로 두어야 함
		if(money<m.price) {
			return; //가격이 현재 보유 금액보다 클 경우 보유금액 고대로 return
		}
		else { //아닐경우에는 조상의 price와 mileage 누적빼기, 합 프린트
			money -= m.price;
			mileage += m.mileage;
		}
		System.out.println("구입명: " + m + " 남은 금액: " + money +" 마일리지 금액: " + mileage);
//		프린트를 m 매개변수로 둠으로써 toString 출력하기
	}
}

 


제목1 

본문

package Lecture;

public class Polymorphism {
	public static void main(String[] args) {
	buyer b = new buyer();
	b.buy(new americano());
	b.buy(new latte());

	System.out.println(b.money);
	}
}

class machine{
	int price; //제품의 가격
	int mileage; //가격대비 마일리지
	
	public machine(int price) {//자손에게서 받아온 가격
		this.price = price; // 자손 클래스에서 받아온 가격을 가져와 조상의 price에 대입
		this.mileage = price / 10;
	}
}

class americano extends machine{
	
	public americano() {
		super(1200); //조상의 멤버변수를 선언하는 super로 조상 생성자 price에 가격대입
	}
	
	public String toString() {
		return "Americano"; //인스턴스를 호출했을 때 return할 값
	}
}

class latte extends machine{
	public latte() {
		super(2000); //위와 동일한 설명
	}
	
	public String toString(){
		return "Latte";
	}
}

class buyer{
	int money = 10000; //보유한 금액이 1만원일 시
	int mileage;
	
	void buy(machine m) {
//		인스턴스 자체를 조상의 변수로 두어 동일한 메서드를 생성하지 않아도 인스턴스 값만 변경하면 값이 도출될 수 있도록 함
//		이 때 조상의 변수로 둔 이유는 자식 인스턴스로 둘 경우에 각각의 자식 인스턴스는 형변환이 불가능하므로 
//		메서드를 추가로 중복 생성해야함 > 코드의 중복 > 매우 bad
//		따라서 americano나 latte가 아닌 조상, 즉 machine으로 두어야 함
		if(money<m.price) {
			return; //가격이 현재 보유 금액보다 클 경우 보유금액 고대로 return
		}
		else { //아닐경우에는 조상의 price와 mileage 누적빼기, 합 프린트
			money -= m.price;
			mileage += m.mileage;
		}
		System.out.println("구입명: " + m + " 남은 금액: " + money +" 마일리지 금액: " + mileage);
//		프린트를 m 매개변수로 둠으로써 toString 출력하기
	}
}
728x90