백엔드/JAVA

콘솔창에 메뉴 만들기 예제 실습 및 이론

두개의 문 2023. 5. 4. 17:51
main() 메소드 내 메뉴 생성

 

▶ console창에 출력할 내용

----- #메뉴# ----- 
1. 커피 
2. 라떼
3. 녹차 
4. 끝 
메뉴 선택해주세요^_^ 

메뉴를 키보드로부터 선택 

선택한 메뉴에 따라 기능 실행 
1번 메뉴 선택 -> "커피를 선택하셨습니다." 
2번 메뉴 선택 -> "라떼를 선택하셨습니다." 
3번 메뉴 선택 -> "녹차를 선택하셨습니다." 
4번 메뉴 선택 -> "감사합니다." 

메뉴에 없는 선택을 할 경우  -> "메뉴에서 선택해주세요."

 

 

▷ 내가 짠 코드

package menu;

import java.util.Scanner;

public class MyMenu {
	public static void main(String[] args ) {
		
		// 1) 배열을 이용한 메뉴판 출력
		String[] menuArray = {"메뉴선택", "커피","라떼","녹차", "끝"};
		
		System.out.println("----- #메뉴# -----");
		
		//		for문을 이용해 배열의 요소 출력
		for( int i=1 ; i < menuArray.length ; i++) {
			System.out.println(i + ". " + menuArray[i]);
		}
		
		//		메뉴 선택하라는 안내문 출력
		System.out.println(
				"\n메뉴를 선택해주세요^_^ ( 커피:1, 라떼:2, 녹차:3, 끝:4 )"
				);
		
		// 2) 선택한 메뉴에 따라 기능 실행 
		// 		키보드로부터 입력 받기 - Scanner클래스 이용
		Scanner sc = new Scanner(System.in);
		
		int answer = sc.nextInt();
		
		switch ( answer ) {
		case 1 :
			System.out.println("커피를 선택하셨습니다. 감사합니다.");
			break;
		case 2 :
			System.out.println("라떼를 선택하셨습니다. 감사합니다.");
			break;
		case 3 :
			System.out.println("녹차를 선택하셨습니다. 감사합니다.");
			break;
		case 4 :
			System.out.println("메뉴 선택이 종료됩니다. 감사합니다.");
			break;
		default :
			if ( answer > 4){
				System.out.println("다시 메뉴를 선택해주세요.");
				answer = sc.nextInt();
			}
		}
	}
}

 

 

 

▷ 수업 마친 후 보안해서 다시 작성해본 코드

< 보안하고 싶은 부분 >

① 메뉴에 없는 번호를 선택 시, 다시 메뉴 입력하라는 문구 및 메뉴 출력 & 다시 스캐너 작동
 - 조건문보다는 반복문이 적합
 - 최소 한번은 메뉴 입력할 수 있도록 반복문 중에서도 do-while문이 적합
 → 반복문 안에 선택한 메뉴별 문구 출력은 조건문으로 
  ∴ 반복문 do-while문 안에 조건문 if문 사용
② do-while의 조건식 : 논리 부정 연산자 이용
 - boolean타입의 변수 menuEnd를 false로 선언
  ( menuEnd = false ;  메뉴 선정이 끝나지 않았다는 의미 )
 - menuEnd가 true가 될 때까지 do-while문 반복

 

		// 논리 부정 연산자 이용해서 반복문 조건식 설정
		boolean menuEnd = false;
		do {	
			Scanner sc = new Scanner(System.in);
			int answer = sc.nextInt();

			if( answer == 1) {
				System.out.println("커피를 선택하셨습니다.");
				menuEnd = true;
			} else if ( answer == 2) {
				System.out.println("라떼를 선택하셨습니다.");
				menuEnd = true;
			} else if ( answer == 3) {
				System.out.println("녹차를 선택하셨습니다.");
				menuEnd = true;
			} else if ( answer == 4) {
				System.out.println("메뉴 선택이 종료됩니다.");
				menuEnd = true;
			} else {
				System.out.println("메뉴에서 선택해주세요.");
			}
		} while(!menuEnd);

③ 메뉴를 다시 선택 시, 메뉴판이 다시 출력되도록 작성
 - do-while문 범위 설정 조정
package menu;

import java.util.Scanner;

public class MyMenu {
	public static void main(String[] args ) {
		
		// 논리 부정 연산자 이용해서 반복문 조건식 설정
		boolean menuEnd = false;
		
		do {	
		// 1) 배열을 이용한 메뉴판 출력
			String[] menuArray = {"메뉴선택", "커피","라떼","녹차", "끝"};
		
			System.out.println("----- #메뉴# -----");
		
		//		for문을 이용해 배열의 요소 출력
			for( int i=1 ; i < menuArray.length ; i++) {
				System.out.println(i + ". " + menuArray[i]);
			}
		
		//		메뉴 선택하라는 안내문 출력
			System.out.println(
				"\n메뉴를 선택해주세요^_^ ( 커피:1, 라떼:2, 녹차:3, 끝:4 )"
				);
		
		// 2) 선택한 메뉴에 따라 기능 실행 
		// 		키보드로부터 입력 받기 - Scanner클래스 이용
			
			Scanner sc = new Scanner(System.in);
			int answer = sc.nextInt();

			if( answer == 1) {
				System.out.println("커피를 선택하셨습니다.");
				menuEnd = true;
			} else if ( answer == 2) {
				System.out.println("라떼를 선택하셨습니다.");
				menuEnd = true;
			} else if ( answer == 3) {
				System.out.println("녹차를 선택하셨습니다.");
				menuEnd = true;
			} else if ( answer == 4) {
				System.out.println("메뉴 선택이 종료됩니다.");
				menuEnd = true;
			} else {
				System.out.println("메뉴에서 선택해주세요.");
			}
		} while(!menuEnd);
		
		System.out.println("감사합니다.");
	}
}

 

▷ 코드 작성하면서 느낀점

처음부터 완벽한 코드 작성은 어려운 거 같다.

우선 글로 최대한 자세히 구현하는 습관을 기르고, 작성된 코드가 내가 생각된대로 실행되는지 단계별로 직접 실행해보면서 체크해나가자.

그 후에 사용자 관점에서 개선해야 할 점을 고려해 코드를 고쳐나가는 것이 중요한 거 같다.  

 

 


메소드

- 메소드 

  · 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것

  · 수학의 함수와 유사 / 입력값을 넣으면 메서드에 의해 결과값이 출력

  ·객체의 동작에 해당하는 중괄호 {  } 블럭을 의미


- 메소드 선언 : 선언부와 실행블록으로 구성

1. 선언부
리턴타입 메소드이름 ( [ 매개변수 선언, ... ] ) {
           
           2. 메소드 실행블록
           : 메소드 호출 시 실행할 코드 작성

}

 

1. 선언부


  ① 리턴타입 : 리턴값의 타입
     - 리턴값 : 메소드를 실행한 후의 결과값
     - 리턴값이 없는 경우, void로 기술
     - 메소드의 리턴값이 있을 경우

      · 반드시 선언부에 리턴타입 기술 ( 일반적으로 변수 선정하여 리턴값을 저장함 )

      · 구현부 { } 안에 return 반환값 ; 이 반드시 포함되어야 함
     - 메소드 정의

// 메소스 정의

void powerOn(){
	System.out.println("TV의 전원이 켜졌습니다.");
}

double divide ( doube x, double y ) {
    double result;
    result = x / y ;
}

     - 메소드 호출 

      · 리턴 타입이 있다고 해서 반드시 리턴값을 변수에 저장할 필요 없음

// 리턴값의 유무에 따라 메소드 호출 방법 다름

powerOn();				

double result = divide(10.0, 5.0);
TV의 전원이 켜졌습니다.
2.0

 

② 메소드 이름 
   - 작성 규칙
    · 숫자로 시작 안됨, '$', '_'를 제외한 특수문자 사용 불가
    · 소문자로 작성
    · 카멜표기법 권장
    ※ 메소드 이름만 보고도 어떤 기능을 하는지 알 수 있도록 이름 짓자.
 
③ 매개 변수 선언
   - 매개 변수 : 메소드가 실행될 때 필요한 외부 데이터를 내부로 전달하는 역할
   - 매개 변수가 항상 필요한 것은 아님

 int divide( int x, int y ){
               int result;
               result = x + y ;
 }

  → divide () 메소드 호출 시, 반드시 2개의 매개변수를 이용해 메소드를 실행시켜야 함
     이 때, 매개값으로 int형이나 int형으로 자동 타입변환될 수 있는 값이어야 함

  - 2개의 매개 변수의 타입이 동일하다고 해서 생략할 수 없음 

    ex ) ( int x, y ) : 생략 불가 

 

  - 매개변수의 개수를 모를 경우 

    ❶ 메소드 정의 시, 배열 타입으로 선언

int sum ( int[] values ) {

}

    ❷ 실행클래스에서 메소드 호출 시, 배열을 넘겨 배열의 항목 값들을 모두 전달 가능 

     ※ 매개 변수를 배열 타입으로 선언할 경우, 메소드 호출 전에 반드시 배열을 생성해야 함     

    →  메소드 호출 시, 배열을 생성시키므로 이 때 배열의 항목 수가 결정됨

- 배열 생성 → 메소드 호출 결과, 리턴값을 변수 result에 저장
   int [] values = { 1, 2, 3 };
   int result = sum( values );
- 위의 문장을 한 줄로 표현
   int result = sum ( int [] values = { 1, 2, 3 } );

 

  → 배열을 생성시키지 않고 값의 목록만 넘겨주는 방법 : 매개변수 ( … ) 사용해 선언 → 메소드 호출 시 쉼표로 나열해주면 됨

메소드 선언 - int sum2 ( int … values ) {      };
메소드 호출 - int result = sum2 ( 1, 2, 3 ) ;

   

▷ 예시

 

 

2. 구현부

 

  - return문 : 현재 실행 중인 메서드를 종료하고 호출한 메서드로 리턴

   ① 리턴값이 있는 메소드

    · 메서드의 반환타입이 'void'가 아닐 경우, 구현부 { } 안에 반드시 return 반환값 ; 포함되어야 함

    → 작업 수행을 마친 후, 반환값이 호출된 메서드로 리턴된다는 의미

    ·  반환값이 메소드 선언부에서 작성한 반환타입과 일치하거나 적어도 자동 형변환이 가능한 것이어야 함

 

int add ( int x, int y ) {
            int result = x + y ;          // 작업 결과를 result 변수에 저장
           return result;                 // result를 호출된 메서드로 리턴
}

→ 메서드 add의 반환타입 ( int )와 반환값 result의 타입 ( int )이 일치해야 함
※ 메서드 내에서 선언된 x, y,  result는 지역변수 → 다른 메서드에서 동일한 이름의 변수 사용 가능

 

  ② 리턴값이 없는 메소드 : void

     · 리턴값이 없는 메소드에서 return문을 메소드 실행을 종료시키는 역할로 사용 가능

   

  ※ 모든 메소드는 적어도 하나 이상의 return문이 있어야 함

     반환타입이 'void'인 경우, return문이 없어도 아무런 문제가 없었던 이유

      →컴파일러가 메서드 마지막에 'return;'을 자동적으로 추가함

※ if문에서 항상 결과값이 반환될 수 있게 주의하기
int min ( int x, int y ){
	if ( x > y ) {
    	return y;
    } else {
        return x;
    }    
}​

 

 


메소드 호출

 

- 메소드를 호출해야만 메소드의 구현부 { } 내에 작성된 문장들이 실행됨

- 메소드 호출

 ① 클래스 내부의 다른 메소드 호출

  · 메소드이름 ( 매개값, … )

  → 매개 변수의 타입과 수에 맞게 매개값 제공해야 함

  · 리턴값이 있는 메소드 호출 후, 그 리턴값을 받고 싶다면 동일하게 변수 선언하고 리턴값 대입

   타입 변수 = 메소드이름 ( 매개값, … )

  → 변수의 타입은 리턴 타입과 동일하거나, 적어도 자동 형변환이 가능해야 함

  

public class ClassName {
	int method1 (int x, int y) {
    	int result = x + y ;
        return result;
    }
    
    void method2 () {
    	int result1 = method1 (10, 20);		// result1 = 30 ( 변수 타입과 리턴 타입 일치 )
        double result2 = method1 (10, 20);	// result2 = 30.0 ( int -> double : 자동 형변환 가능 )
    }
}

 

 ② 클래스 외부에서 메소드 호출

    ❶ 객체 먼저 생성

        메소드는 객체에 소속된 멤버 → 객체가 생성되어야 사용할 수 있음

        즉, 객체가 존재하지 않으면 메소드도 존재하지 않음

        클래스이름 변수이름 = new 클래스이름();

    ❷ 메소드 호출

      - 도트(.) 연산자 : 객체 접근 연산자로 객체가 가지고 있는 변수나 메소드에 접근 가능      

        참조변수 . 메소드 ( 매개값, … );

      

  

 


계산기를 이용한 메소드 정의 및 호출

 

< 계산기의 비즈니스 로직  >
1. 계산기의 전원을 켠다.
2. 간단한 사칙연산을 한다. ( 덧셈, 뺄셈, 곱셈, 나눗셈 )
3. 계산기의 전원을 끈다. 

※ 비즈니스 로직(Business Logic)이란?

  : 사용자의 눈에는 보이지는 않지만, 사용자가 바라는 결과물을 올바르게 도출할 수 있도록 짜여진 코드 로직을 의미

 

 

1. 데이터 클래스

  : 프로그램을 실행시키기 위해 필요한 데이터를 한 곳에 모은 클래스 → 사용자 정의 데이터형 / 참조자료형 

package calc;

public class Calculator {
	// 메소드 정의
	void powerOn() {
		System.out.println("계산기의 전원을 켰습니다.");
	}
	
	void powerOff() {
		System.out.println("계산기의 전원을 껐습니다.");
	}
    
	// +
	double add(double x, double y) {
		double result = x + y ;			// 첫번째 방법
	    return result;			 
		//return x + y;			        // 두번째 방법
	}
    
	// -
	double sub(double x, double y) {
		return x - y;
	}
    
	// *
	double mul(double x, double y) {
		return x * y;
	}
    
	// /
	double div(double x, double y) {
		return x / y;
	}
}

 

2. 실행 클래스 - 객체 생성 및 메소드 호출

package calc;

public class CalculatorApp {

	public static void main(String[] args) {
		Calculator calc = new Calculator();

		// 1. 계산기 전원을 켠다.
		calc.powerOn();
		
		// 계산기의 계산결과 저장변수 
		double result = 0.0; 	
		double x = 0.0;
		double y = 0.0;
        
        	// 2. 간단한 사칙연산을 한다. 
		// 덧셈
		x = 100.0;
		y = 200.0;
		result = calc.add(x, y);
		print(x, y, "+", result);
		
		// 뺄셈
		result = calc.sub(x, y);
		print(x, y, "-", result);
		
		// 곱셈
		result = calc.mul(x, y);
		print(x, y, "*", result);
		
		// 나눗셈
		result = calc.div(x, y);
		print(x, y, "/", result);
        
       		// 3. 계산기 전원을 끈다.
		calc.powerOff();
        
        }
 }
계산기의 전원을 켰습니다.
100.000000 + 200.000000 = 300.000000
100.000000 - 200.000000 = -100.000000
100.000000 * 200.000000 = 20000.000000
100.000000 / 200.000000 = 0.500000
계산기의 전원을 껐습니다.

 

▷ 외부 클래스에서 메소드 호출

  → 객체 먼저 생성 후, 메소드 호출

 

※ 지역변수 ( local variable ) : 반드시 초기화해주어야 에러나지 않음
   - 클래스 이외의 영역, 즉 메서드, 생성자, 초기화 블럭 내부에서 선언됨
   - 메서드 내에 선언되어 메서드 내에서만 사용 가능 →  메서드 종료 시 소멸됨

   - 스택 영역에 저장되며, 초기화하지 않으면 의미없는 값으로 초기화됨

	// 계산기의 계산결과 저장변수 
	double result = 0.0; 	
	double x = 0.0;
	double y = 0.0;

 

 


자동차 가스 주입 

 

< 가스 자동차의 gas가 떨어지면 어떻게 될까? >
1. 현재 가스의 양을 수치로 확인 
2. 남아있는 가스의 유무 판단 ( 있다, 없다)
3. 시동을 걸고 자동차가 달리는 동안남아있는 가스량 체크 → 가스가 떨어지면 주입하라는 문구 출력
                            반복문 사용               반복문 안에 조건문 if문 사용

 

▶ console창에 출력할 내용

gas가 있습니다.
출발합니다.
자동차 시동을 걸었습니다.
달립니다. (gas잔량 : 5)
달립니다. (gas잔량 : 4)
달립니다. (gas잔량 : 3)
달립니다.(gas잔량 : 2)
달립니다. (gas잔량 : 1)
차가 곧 멈춥니다.
gas가 없습니다.
가스 주입해주세요.

 

1. 데이터 클래스

package car;

public class MyCar {
	int gas;
	
	void setGas(int gas) {
		this.gas = gas;
	}
	
	boolean isLeftGas () {
		if (gas == 0) {
			System.out.println("gas가 없습니다.");
			return false;
		} else {
			System.out.println("gas가 있습니다.");
			return true;
		}
	}
	
	void run() {
		start();
		
		while ( true ) {
			if(gas > 0) {
				System.out.println("달립니다. (gas잔량 : " + gas + ")");
				gas -= 1;
			} else {
				System.out.println("차가 곧 멈춥니다.");
				return;
			}
		}	
	}
	
	void start() {
		System.out.println("자동차 시동을 걸었습니다.");
	}
}

 

2. 실행 클래스

package car;

public class MyCarApp {

	public static void main(String[] args) {
		
		MyCar myCar = new MyCar();
		
		myCar.setGas(5);
	    //System.out.println(myCar.gas);
	    
	    boolean GasState = myCar.isLeftGas();
	    if ( GasState == true ) {
	    	System.out.println("출발합니다.");
	    	myCar.run();
	    }
	    
	    if ( myCar.isLeftGas()) {
	    	System.out.println("가스 주입할 필요가 없습니다.");
	    } else {
	    	System.out.println("가스 주입해주세요.");
	    }
	}
}