organize/자바

Java 12

001cloudid 2024. 4. 24. 15:44
728x90

매개변수의 다형성

다형성의 장점 다형적 매개변수, 하나의 배열로 여러 종류 객체 다루기
다형성 : 조상타입의 참조변수로 자손객체를 다룸. 참조변수의 형 변환(사용가능한 멤버 개수로). instanceof연산자(형 변환 가능 여부 확인)

매개변수의 다형성
참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있음

 

package chapter07;

class ProductS14E1{
	int price; //제품가격
	int saleRatio; //할인율
}

class TvS14E1 extends ProductS14E1{
	
}

class ComputerS14E1 extends ProductS14E1{
	
}

class AudioS14E1 extends ProductS14E1{
	
}

class BuyerS14E1{ //구매자
	int money = 1000000; //소유 금액
	int saleRatio = 0;
	
	//오버로딩
//	void buy(TvS14E1 t) {
//		money -= t.price;
//		saleRatio += t.saleRatio;
//	}
//	
//	void buy(ComputerS14E1 c) {
//		money -= c.price;
//		saleRatio += c.saleRatio;
//	}
//
//	void buy(AudioS14E1 a) {
//		money -= a.price;
//		saleRatio += a.saleRatio;
//	}
	//문제점 : 제품이 늘어날수록 오버로딩을 해줘야함. => 번거롭고 코드의 중복 발생
	
	//조상타입으로 여러 물건을 구매할 수 있음
	void buy(ProductS14E1 p){
		money -= p.price;
		saleRatio = p.saleRatio;
	}
	
}

public class Study14Ex1 {

	public static void main(String[] args) {

		BuyerS14E1 buyer = new BuyerS14E1();
		
		TvS14E1 tv = new TvS14E1();
		ComputerS14E1 com = new ComputerS14E1();
		AudioS14E1 audio = new AudioS14E1();
		
		buyer.buy(tv);
		buyer.buy(com);
		buyer.buy(audio);
		
	}
	
}

 

package chapter07;

class ProductS14Ex2{
	int price; //제품가격
	int bonusPoint; //제품구매시 제공하는 보너스점수
	
	ProductS14Ex2(int price){
		this.price = price;
		bonusPoint = (int)(price/10); //보너스점수는 제품 가격의 10%
	}
}

class TvS14E2 extends ProductS14Ex2{
	TvS14E2(){
		//부모(조상)클래스의 생성자 Product(int price)를 호출
		super(100); // Tv의 가격을 100으로 함
	}
	
	public String toString() { //Object 클래스의 toString()을 오버라이딩
		return "Tv";
	}
}

class ComputerS14E2 extends ProductS14Ex2{
	ComputerS14E2(){
		super(150);
	}
	
	public String toString() {
		return "Computer";
	}
}

class BuyerS14E2{ //고객
	int money = 300; //고객이 가지고 있는 금액
	int bounsPoint = 0; //보너스포인트
	
	void buy(ProductS14Ex2 p) {
		if(money < p.price) {
			System.out.println("현재 보유하신 금액으로는 구매하실 수 없습니다.");
			return;
		} 
		money -= p.price;
		bounsPoint += p.bonusPoint;
		System.out.println(p + "를 구매하였습니다.");
	}
}

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

		BuyerS14E2 buyer = new BuyerS14E2();

		//1
		TvS14E2 tv = new TvS14E2();
		ComputerS14E2 com = new ComputerS14E2();
		
//		buyer.buy(tv);
//		buyer.buy(com);
		
		//2
		buyer.buy(new TvS14E2()); 
		//== ProductS14E2 p = new TvS14E2; buyer.buy(p);를 합친 것
		//즉, int i = 10; System.out.println(i); == System.out.println(10);
		buyer.buy(new ComputerS14E2());
		
		System.out.println("현재 남은 돈은 " + buyer.money);
		System.out.println("현재 보너스 점수는 " + buyer.bounsPoint);
	}

}

 

여러 종류의 객체를 배열로 담기

다형성 장점
1. 다형적 매개변수
2. 하나의 배열에 여러 종류 객체 저장
배열은 하나의 타입으로만 할 수 있지만 다형성을 이요하면 여러 종류의 객체를 저장할 수 있음

여러 종류의 객체를 배열로 다루기
조상타입의 배열에 자손들의 객체를 담을 수 있음
Product p1 = new Tv(); Product p2 = new Computer(); Product p3 = new Audio();
==> Product p[] = new Product[3]; p[0] = new Tv(); p[1] = new Computer(); p[3] = new Audio();

 

package chapter07;

class ProductS15E1{
	int price; //제품 가격
	int bonusPoint; //제품 구매 시 보너스포인트
	
	ProductS15E1(int price) {
		this.price = price;
		bonusPoint = price/10;
	}
	
	ProductS15E1() {} //기본 생성자

}

class TvS15E1 extends ProductS15E1{
	TvS15E1() {
		super(100);
	}
	
	public String toString() {
		return "Tv";
	}
}

class ComputerS15E1 extends ProductS15E1{
	ComputerS15E1(){
		super(150);
	}
	
	public String toString() {
		return "Computer";
	}
}

class AudioS15E1 extends ProductS15E1{
	AudioS15E1(){
		super(50);
	}
	
	public String toString() {
		return "Audio";
	}
}

class BuyerS15E1{ //고객
	int money = 500; //고객이 소유한 금액
	int bonusPoint = 0; //고객의 보너스포인트
	ProductS15E1[] cart = new ProductS15E1[10]; //구입한 제품을 저장하기 위한 배열
	int i = 0;
	
	void buy(ProductS15E1 p) {
		if(money < p.price) {
			System.out.println("잔액이 부족하여 구매할 수 없습니다.");
		}
		
		money -= p.price; //가진 돈에서 구입한 제품의 가격을 뺌
		bonusPoint += p.bonusPoint; //제품의 보너스 포인트를 추가
		cart[i++] = p; //제품을 Product[] cart에 저장
		System.out.println(p+" 제품을 구매하였습니다.");
	}
	
	void summary() { //구매한 물품에 대한 정보를 요약
		int sum = 0;  //구입한 물품의 합계
		String itemList = ""; //구입한 물품목록
		
		//반복문을 이용해 구입한 물품의 총 가격과 목록을 만듦
		for(int i = 0; i<cart.length;i++) {
			if(cart[i]==null) {
				break;
			} else {
				sum += cart[i].price;
				itemList += cart[i] + " ";
			}
			
			System.out.println("구입하신 물품의 총액은 " + sum + "입니다.");
			System.out.println("구입하신 제품은 " + itemList + "입니다.");
			System.out.println("고객님께서 소지하신 돈은 \"" + Math.abs(money - sum)+"\" 입니다." );
		}
		
	}
}

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

		BuyerS15E1 b = new BuyerS15E1();
		b.buy(new TvS15E1());
		b.buy(new ComputerS15E1());
		b.buy(new AudioS15E1());
		b.summary();
		
		
	}

}

 

추상 클래스, 추상 메서드

추상 클래스(abstract class) => 미완성 설계도
추상메서드(미완성 메서드)를 갖고 있는 클래스(Study16Ex1)
인스턴스 생성 불가(다른 클래스 작성에 도움을 주기 위한 것)
상속을 통해 추상 메서드를 완성해야 인스턴스 생성 가능. 추상메서드 구현부를 만드는 것을 구현이라고 함.(Study16Ex1)

 

package chapter07;

//추상메서드(미완성 메서드)를 갖고 있는 클래스
abstract class PlayerS16E1{ //추상클래스
	abstract void play(int pos); //추상 메서드(구현부가 없는 미완성 메서드)
	abstract void stop(); //추상 메서드
}

//상속을 통해 추상 메서드를 완성해야 인스턴스 생성가능
class AudioPlayerS16E1 extends PlayerS16E1{
	@Override
	void play(int pos) {
		// TODO Auto-generated method stub
	}

	@Override
	void stop() {
		// TODO Auto-generated method stub
	}

}

public class Study16Ex1 {

}

 

추상 메서드(abstract method) => 미완성 메서드
주석을 통해 어떤 기능을 수행할 목적으로 작성하였는지 설명
구현부가 없는 메서드
abstract 리턴타입 메서드이름();
꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우 사용)(Study16Ex2)

 

package chapter07;

abstract class PlayerS16E2{
	abstract void play(int pos);
	abstract void stop();
}

class AudioPlayerS16E2 extends PlayerS16E2{
	void play(int pos) {
		// TODO Auto-generated method stub
		
	}

	void stop() {
		// TODO Auto-generated method stub
		
	}
}

//미완성 => abstract 클래스로 만들어줌
abstract class AbstractPlayerS16E2 extends PlayerS16E2{
	void play(int pos) {
		
	}
}


public class Study16Ex2 {

}

 

package chapter07;

//추상 메서드 호출 가능(호출할 때는 선언부만 필요)

abstract class PlayerS16E3{
	
	boolean pause; //일시정지 상태를 저장하기 위한 변수
	int currentPos; //현재 Play되고 있는 위치를 저장하기 위한 변수
	
	//추상 클래스도 생성자가 있어야함
	PlayerS16E3(){
		pause = false;
		currentPos = 0;
	}
	
	//지정된 위치(pos)에서 재생을 시작하는 기능이 수행하도록 작성되어야 함
	abstract void play(int pos); //추상메서드
	
	//재생을 즉시 멈추는 기능을 수행하도록 작성되어야 함
	abstract void stop();
	
	//인스턴스 메서드 => 객체 생성 후 사용 가능
	void play() {
		play(currentPos); //메서드는 선언부만 알면 호출 가능하므로 추상 메서드를 사용할 수 있음.
	}
}

//추상 클래스는 상속을 통해 완성해야 객체 생성 가능
class AudioS16E3 extends PlayerS16E3{
	void play(int pos) {
		System.out.println(pos + "번 부터 play합니다.");
	}
	void stop() {
		System.out.println("재생을 멈춥니다.");
	}
}

public class Study16Ex3 {

	public static void main(String[] args) {

//		PlayerS16E3 playerS16E3 = new PlayerS16E3(); 추상 클래스의 객체 생성 => X
		AudioS16E3 audio = new AudioS16E3();
		PlayerS16E3 audio1 = new AudioS16E3(); //다형성으로 가능
		
		audio.play(100);
		audio.stop();
		
		System.out.println();
		
		audio1.play(200);
		audio1.stop();
		
	}
	
}

 

추상클래스의 작성

여러 클래스에 공통적으로 사용될 수 있는 추상클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상 클래스를 만듦
추상화(불명확) ←→ 구체화(명확, 구체적)
추상화된 코드는 구체화된 코드보다 유연(변경에 유리함)

package chapter07;

abstract class TransS17E1{
	
	int x, y;
	abstract void move(int x, int y);
	void stop() {}
}

class CarS17E1 extends TransS17E1{
	void move(int x, int y) {
		System.out.println("Car [x = " + x + ", y = " + y + "]");
	}
	void accelerate() {
		System.out.println("지상으로 이동");
	}
}

class AirplaneS17E1 extends TransS17E1{
	void move(int x, int y) {
		System.out.println("Car [x = " + x + ", y = " + y + "]");
	}
	void fly() {
		System.out.println("하늘로 이동");
	}
}

class BicycleS17E1 extends TransS17E1{
	void move(int x, int y) {
		System.out.println("Car [x = " + x + ", y = " + y + "]");
	}
	void pedal() {
		System.out.println("페달을 밟아 이동");
	}
}

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

		TransS17E1[] group = {new CarS17E1(), new AirplaneS17E1(), new BicycleS17E1()}; //배열의 생성과 초기화를 한 번에 한 문장
		/* ==
		 * TransS17E1[] group = new TransS17E1[3]; //객체 배열 : 참조 변수 묶음
		 * group[0] = new CarS17E1();
		 * group[1] = new AirplaneS17E1();
		 * group[2] = new BicycleS17E1();
		*/
		
		//group 타입은 TransS17E1[]이고,
		//group[0], group[1], group[2]의 타입은 TransS17E1
		for(int i = 0; i<group.length; i++) {
			group[i].move(10, 20);
		}
		/* ==
		 * group[0].move(10,20); //CarS17E1 객체의 move(10,20)을 호출
		 * group[1].move(10,20); //AirplaneS17E1 객체의 move(10,20)을 호출
		 * group[2].move(10,20); //BicycleS17E1 객체의 move(10,20)을 호출
		 */
		
	}

}

 

728x90

'organize > 자바' 카테고리의 다른 글

Java 14  (0) 2024.04.28
Java 13  (0) 2024.04.25
Java 11  (0) 2024.04.23
Java 10  (0) 2024.04.22
Java 9  (0) 2024.04.21