재밌고 어려운 IT를 이해해보자~!

상속을 이용한 팀프로젝트 본문

PROJECT

상속을 이용한 팀프로젝트

언제나즐거운IT 2023. 12. 5. 00:03

오늘은 상속을 공부하기 위해서 CRUD 설게부터 한글코딩 실제코딩까지 팀원들과 함께 정리해보았다!

 

세세하게 들어가면 함수명, 변수명부터 어떤기능을 구현할지, 어떻게 구현할지, 같은 구현이라도 다른코드가 나올 수 있고, 생각들도 다들 다양하다.  따라서 모두가 100%만족하는 프로그램을 만들기는 쉽지 않다.

이번 프로젝트를 진행하면서는 사소한부분들에 대해서는 의견이 나오면 빠르게 수용을 했고, 기능구현이나 생각이 좀 필요한 부분들에 있어서는 여러 의견을 들어보고 천천히 구성을 진행 했었다. 프로그램을 제작하면서 서로 이해가 안가는 부분들도 잘 해소해 가면서 진행이 되었던것 같아서 좋았다!

 

한가지 어려웠던 점은 수업을 들으면서 배웠던 배열내 최댓값 찾기 로직을 팀원들과 함께 구성하고 있었다.

분명 수업때는 완벽하게 이해했고 코드를 보지않고 로직을 구성할 수 있다고 생각했지만, 서로서로 의견을 내고 받아들이는 과정에서 뭔가 머리가 빙글빙글 돌았다. 그런 부분에 대해서는 의사소통이 좀 더 잘되어야 한다고 생각한다. 그리고 아직 부족하다고 느끼는 점은 팀원이 ~이렇게 하면 되지 않을까요? 라고 코드를 알려주실때, 바로바로 머릿속에서 코드가 돌아가지 않아서 답변을 드리기가 어려웠디. 그런 부분에서는 더 많은 타이핑을 해보고, 코드를 더 자주 봐야할 것같다. 

 

CRUD 설계

			
C
차량구매
              
R
차량전체정보출력
차량1개정보출력
보유하고 있는것 중에 제일비싼차조회
              
U
전기차타입만 출력후 베터리 완충
연료타입만 출력후 연료 완충 
루프 동작
시동 온오프

D 
차 매각

 

한글코딩

package teamproject;
public class Car {
	public static void main(String[] args) {
		/* 자동차 클래스 (부모)
		 * 멤버변수
		 * 1. String 브랜드 brand
		 * 2. String 모델 model
		 * 3. String 색깔 color
		 * 4. int 가격 price
		 * 5. int 연료 fuel
		 * 6. static boolean 엔진 engine false
		 * -> boolean으로 설정한 이유 : 시동이 켜지면 true 시동이 꺼지면
		 * false로 메서드로 제어하기 위해서.
		 *
		 *  모든 차량은 부모의 멤버변수를 가지고 있다.
		 *
		 *  생성자
		 *  자동차 (브랜드, 모델, 색깔, 가격) {
		 *  최초 구매시 연료는 30으로 고정
		 *  최초 구매시 엔진은 꺼져있는 상태.
		 *
		 *  Car(브랜드, 모델, 색깔, 가격) {
		 *  최초 구매시 연료는 30으로 고정
		 *  this.fuel = 30;
		 *  }
		 *
		 *  메서드
		 *  시동켜짐()
		 *  void on() {
		 *  System.out.println("시동이 켜졌습니다.");
		 *	시동꺼짐()
		 *	void off() {
		 *  System.out.println("시동이 꺼졌습니다.");
		 *  }
		 *  연료충전()
		 *  void fill () {
		 *  Scanner sc = new Scanner(System.in)
		 *  System.out.println("현재 연료 잔량" + this.fuel+ "입니다.")
		 *  System.out.println("충전가능 범위 " + (100 - this.fuel)+"~100")
		 *  System.out.println("연료를 얼마나 충전하시겠습니까?")
		 *  int answer = sc.nextInt();
		 *  반복문이랑 조건문을 사용해서 정삭적인 범위내 입력하지 않았으면 다시 입력 받는다.
		 *  this.fuel += answer;
		 *  System.out.println("충전이 완료 되었습니다. 현재 연료 잔량 " + this.fuel +"입니다.");
		 *  }
		 *  차량정보출력() {
		 *  System.out.println("브랜드: "+this.name+" 모델: "+this.model+" 색깔: "+this.color
		 *	+" 가격: "+this.price+"+"연료: " +this.fuel);
		 *	}
		 *
		 *  자식클래스
		 *  전기자
		 *
		 *  멤버변수
		 *  베터리(전기차만 가지고 있는 속성)
		 *
		 *  생성자
		 *
		 *  전기차 (브랜드, 모델, 색깔, 가격)
		 *  최초 구매시 베터리 잔량은 30
		 *
		 *
		 *  ElecCar (브랜드, 모델, 색깔, 가격)
		 *  슈퍼 (브랜드, 모델, 색깔, 가격)
		 *  this.battery = 30;
		 *
		 *  메서드
		 *  @오버라이딩
		 *  시동켜짐(버튼으로 켜짐)
		 *  void on() {
		 *  System.out.println("버튼으로 시동이 켜졌습니다");
		 *  }
		 *  시동꺼짐(버튼으로 꺼짐)
		 *  void off() {
		 *  System.out.println("버튼으로 시동이 꺼졌습니다");
		 *  }
		 *  베터리충전(0~300분 까지)
		 *  void batteryCharge () {
		 *
		 *  Scanner sc = new Scanner(System.in)
		 *  System.out.println("현재 베터리 잔량" + this.battery + "%입니다.")
		 *  System.out.println("충전가능 범위 " + (100 - this.battery)+"%~100%")
		 *  System.out.println("베터리를 얼마나 충전하시겠습니까?")
		 *  int answer = sc.nextInt();
		 *  반복문이랑 조건문을 사용해서 정삭적인 범위내 입력하지 않았으면 다시 입력 받는다.
		 *  this.battery += answer;
		 *  System.out.println("충전이 완료 되었습니다. 현재 베터리 잔량 " + this.battery +"%입니다.");
		 *  }
		 *  차량정보출력

실제코딩

// 초안(ver 1.0)
// 1차 수정(ver 1.1) > 김진영
// - 차량 구매 부분 모듈화
// - 슈퍼카 roof 개폐기능 추가
// - 선택차량 시동 on/off기능 추가
// 2차 수정(ver1.2) > 정석진
// - 일반차량과 슈퍼카의 시동상태가 동일하게 변하는 내용 수정
// - 전기차량의 메소드 내부 엔진상태변화를 통제하는 변수의 미사용
// 3차 수정(ver 1.3) > 하정희
// - 연료충전 부분이 충전완료이후 초기메뉴로 넘어가지지 않는 현상 수정
// 4차 수정(ver 1.4)
// - 차량정보입력함수 파라미터 3개에서 1개로 수정(코드 경량화)

package teamProject;

import java.util.Scanner;

class Car {
	// 멤버변수
	String color;
	String brand;
	String model;
	int price;
	int fuel;
	boolean engine;

	// 생성자
	Car(String color, String brand, String model, String price) {
		this.color = color;
		this.brand = brand;
		this.model = model;
		this.price = Integer.parseInt(price) / 10000000;
		this.fuel = 30;
	}

	// 메서드
	void on() {
		this.engine = true;
		System.out.println("시동이 켜졌습니다");
	}

	void off() {
		this.engine = false;
		System.out.println("시동이 꺼졌습니다");
	}

	void fill() {
		Scanner sc = new Scanner(System.in);
		System.out.println("현재 연료 잔량" + this.fuel + "입니다.");
		System.out.println("충전가능 범위 " + "0 ~ " + (100 - this.fuel));
		System.out.println("연료를 얼마나 충전하시겠습니까?");
		while (true) {
			int answer = sc.nextInt();
			if (0 <= answer && answer <= 100 - this.fuel) {
				this.fuel += answer;
				System.out.println("충전이 완료 되었습니다. 현재 연료 잔량 " + this.fuel + " 입니다.");
				break;
			} else {
				System.out.println("충전가능한 범위를 초과하였습니다 다시입력하세요");
			}
		}
	}

	void printInfo(int i) {
		System.out.println(i+1+"번 차량 >> 브랜드: " + this.brand + " 모델: " + this.model + " 색깔: " + this.color + " 가격: " + this.price
				+ "천만원" + " 연료: " + this.fuel + "/100");
	}
}

class ElecCar extends Car {
	int battery;

	ElecCar(String color, String brand, String model, String price) {
		super(color, brand, model, price);
		this.battery = 30;
	}

	@Override
	void on() {
		engine = true;
		System.out.println("버튼으로 시동이 켜졌습니다");
	}

	@Override
	void off() {
		engine = false;
		System.out.println("버튼으로 시동이 꺼졌습니다");
	}

	@Override
	void fill() {
		Scanner sc = new Scanner(System.in);
		System.out.println("현재 배터리 잔량" + this.battery + "% 입니다.");
		System.out.println("충전가능 범위 " + "0% ~ " + (100 - this.battery) + "%");
		System.out.println("배터리를 얼마나 충전하시겠습니까?");
		while (true) {
			int answer = sc.nextInt();
			if (0 <= answer && answer <= 100 - this.battery) {
				this.battery += answer;
				System.out.println("충전이 완료 되었습니다. 현재 배터리 잔량 " + this.battery + "% 입니다.");
				break;
			} else {
				System.out.println("충전가능한 범위를 초과하였습니다 다시입력하세요");
			}
		}
	}

	@Override
	void printInfo(int i) {
		System.out.println(i+1+"번 차량 >> 브랜드: " + this.brand + " 모델: " + this.model + " 색깔: " + this.color + " 가격: " + this.price
				+ "천만원 " + "연료: " + this.battery + "%");
	}

}

class SuperCar extends Car {
	boolean roof;

	SuperCar(String color, String brand, String model, String price) {
		super(color, brand, model, price);
		roof = false;
	}

	@Override
	void on() {
		engine = true;
		System.out.println("지문으로 시동이 켜졌습니다");
	}

	@Override
	void off() {
		engine = false;
		System.out.println("지문으로 시동이 꺼졌습니다");
	}

	@Override
	void printInfo(int i) {
		System.out.print(i+1+"번 차량 >> 브랜드: " + this.brand + " 모델: " + this.model + " 색깔: " + this.color + " 가격: " + this.price
				+ "연료: " + this.fuel+"/100");
		if (!roof) {
			System.out.println(" 현재 루프가 닫혀있습니다");
		} else {
			System.out.println(" 현재 루프가 열려있습니다");
		}
	}

	void roofOpen(int i) {
		roof = true;
		System.out.println(i+1+"번차량 루프가 열렸습니다");
	}

	void roofClose(int i) {
		roof = false;
		System.out.println(i+1+"번차량 루프가 닫혔습니다");
	}

}

public class Main {
	public static void msg(int i) {
		String[] msg1 = { "브랜드 입력 >> ", "모델 입력 >> ", "색상 입력 >> ", "가격 입력 >> " };
		System.out.println(msg1[i]);
	}

	// 차량 정보 입력 로직
	public static String[] input(Scanner sc) {
		String[] ans = new String[4];
		for (int i = 0; i < ans.length; i++) {
			msg(i); //메서드 호출
			ans[i] = sc.next();
		}
		return ans;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		Car[] car = new Car[3];
		int option, index = 0;
		while (true) {
			System.out.println("======================");
			System.out.println("==== 차량구매 프로그램 ====");
			System.out.println("======================");
			System.out.println("1. 차량 구매");
			System.out.println("======================");
			System.out.println("2. 차량목록 전체 출력");
			System.out.println("======================");
			System.out.println("3. 가장 비싼 차량정보 출력");
			System.out.println("======================");
			System.out.println("4. 연료 충전");
			System.out.println("======================");
			System.out.println("5. 루프 동작");
			System.out.println("======================");
			System.out.println("6. 시동 켜기/끄기");
			System.out.println("======================");
			System.out.println("7. 차량 매각");
			System.out.println("======================");
			System.out.println("0. 프로그램 종료");
			System.out.println("======================");
			System.out.println("입력 >> ");
			int action = sc.nextInt();
			if (action == 0) {
				System.out.println("프로그램을 종료합니다 . . .");
				break;
			} else if (action == 1) {
				if (index >= 3) {
					System.out.println("더이상 구매하실 수 없습니다");
					continue;
				}
				System.out.println("=====   차량구매   =====");
				System.out.println("1. 일반차");
				System.out.println("2. 전기차");
				System.out.println("3. 슈퍼카");
				System.out.println("입력 >> ");
				option = sc.nextInt();
				String[] ans = input(sc);
				if (option == 1) {
					car[index++] = new Car(ans[2], ans[0], ans[1], ans[3]);
				} else if (option == 2) {
					car[index++] = new ElecCar(ans[2], ans[0], ans[1], ans[3]);
				} else if (option == 3) {
					car[index++] = new SuperCar(ans[2], ans[0], ans[1], ans[3]);
				} else {
					System.out.println("잘못 입력하셨습니다");
					continue;
				}
			} else if (action == 2) {
				if (index <= 0) {
					System.out.println("구매하신 차량이 없습니다");
					continue;
				}
				System.out.println("전체목록출력");
				for (int i = 0; i < index; i++) {
					System.out.print(i + 1 + "번 차량 >");
					car[i].printInfo(i);
				}
			} else if (action == 3) {
				if (index <= 0) {
					System.out.println("구매하신 차량이 없습니다");
					continue;
				}
				int maxInd = 0;
				System.out.println("가장 비싼차를 출력합니다");
				for (int i = 1; i < index; i++) {
					if (car[i].price > car[maxInd].price) {
						maxInd = i;
					}
				}
				System.out.println("제일 비싼차는 " + car[maxInd].model + "입니다");
				System.out.println("가격은 " + car[maxInd].price + "천만원 입니다");
			} else if (action == 4) {
				if (index <= 0) {
					System.out.println("구매하신 차량이 없습니다");
					continue;
				}
				System.out.println("1. 전기차 충전");
				System.out.println("2. 일반차 충전 또는 슈퍼카충전");
				System.out.print("번호 입력>> ");
				option = sc.nextInt();
				if (option == 1) {
					for (int i = 0; i < index; i++) {
						if ((car[i] instanceof ElecCar)) {
							car[i].printInfo(i);
						}
					}
					System.out.print("차 번호 입력 >> ");
					option = sc.nextInt();
				if (1 <= option && option <= index) {
					if ((car[option-1] instanceof ElecCar)) {
							car[option-1].fill();
							continue;
						}else{System.out.println("입력하신 번호는 전기차가 아닙입니다");
								continue;
					}
				}else{System.out.println("없는 번호입니다");
}
				} else if (option == 2) {
					for (int i = 0; i < index; i++) {
						if (!(car[i] instanceof ElecCar)) {
							car[i].printInfo(i);
						}
					}
					System.out.print("차 번호 입력 >> ");
					option = sc.nextInt();
				if (1 <= option && option <= index) {
					if (!(car[option-1] instanceof ElecCar)) {
							car[option-1].fill();
							continue;
						}else{System.out.println("입력하신 번호는 전기차입니다");
								continue;
					}
				}else{System.out.println("없는 번호입니다");
}
}
				continue;  //연료충전 후 초기메뉴로 이동 #수정됨
			} else if (action == 5) {
				if (index <= 0) {
					System.out.println("구매하신 차량이 없습니다");
					continue;
				}
				for (int i = 0; i < index; i++) {
					if (car[i] instanceof SuperCar) {
						if(!((SuperCar)car[i]).roof) {
							((SuperCar) car[i]).roofOpen(i); // 슈퍼카 라면 열리게하는 기능
						}else {
							((SuperCar) car[i]).roofClose(i); //닫히는 기능도 구현
						}
					}else {
						continue;
					}
				}
			} else if (action == 6) {
				if (index <= 0) {
					System.out.println("구매하신 차량이 없습니다");
					continue;
				}
				System.out.print("차 번호 입력 >> ");
				option = sc.nextInt();
				if (1 <= option && option <= index) {
					if (!car[option - 1].engine) {
						car[option - 1].on();
					} else {
						car[option - 1].off();
					}
				}
			} else if (action == 7) {
				if (index <= 0) {
					System.out.println("구매하신 차량이 없습니다");
					continue;
				}
				System.out.println("가장 최근에 구입한차량 매각합니다");
				index--;
			}
		}
	}
}

 

피드백 

초안 작성 이후 2번의 수정과정을 거쳤는데 루프동작과 시동동작 기능을 메인쪽에서 다루지 않았었다. 따라서 

해당 부분을 수정했고, 메인문의 브랜드, 모델, 색상, 가격 물어보는것을 모듈화해서 훨씬 깔끔해졌다!
모듈화의 중요성을 느꼈다.

 

2차수정으로는 static boolean engine으로 선언한 부분에서 각 클래스들이 engine 변수를 객체와 무관하게 공유자원으로 사용하는 것이 문제였다. static을 지워주니 객체와 관련이 있게 되어서 각 클래스마다의 엔진 상태를 컨트롤 할 수 있었다.

static의 대한 정의가 잘 이해가 안됐었는데 이번기회에 더 확실하게 이해가 된 것 같다.

 

모든 On Off 쪽에서 On / Off 두가지 기능밖에 없기때문에 상태에 따라서 다른상태로 동작하는것 밖에 안된다면, 하나의 함수로 통일하고 engineTrigger(), roofTrigger 같은 느낌으로 한개의 함수만 만들면 개인적으로는 좋을 것 같다.

 

유저에게 차량구매관련 질문을 하는 부분에서 브랜드 모델 색상 가격 에 따라 ans1,2,3,4, 가 될 수 있도록 생성자를 선언할때 받는 매게변수를 순서에 맞춰서 선언해 주면 좋을 것 같다.

 

 

'PROJECT' 카테고리의 다른 글

MyPage 및 Report 정리 [TEAM PROJECT]  (0) 2024.01.30
MVC 패턴, DB를 활용한 Team Project Part. 1  (0) 2024.01.13
CRUD설계 후 진행한 Team Project  (0) 2023.12.13
Comments