# 14. Java 13일차(230831) [국비교육]

brand_mins·2023년 8월 31일

Java

목록 보기
14/47

1. 메소드

(1) 함수

  • 복잡한 코드를 미리 만들어 놓고 필요할때 사용함
  • 복잡한 수식을 기호화
  • 내부에 어떻게 동작하는지 몰라도 실행결과를 화면에 출력하는 함수
  • 반복되는 코드를 쉽게 재사용
  • 선언부: 함수를 어떻게 동작시킬지 결정
  • 호출부: 함수를 호출함

1) 1달러 1161원, 6달러가 우리나라 돈으로 얼마인지 구하는 함수

f(x) = x * 1161;
exchange = 6 * 1161;

2) 구입할 컵의 개수와 가격을 통해 비용을 계산하는 함수

f(x,y) = x * y;
CupSum(cupCount, cupPrice) = cupCount * cupPrice;

3) 섭씨, 화씨 구하는 함수

// 섭씨 : 물의 어는점과 끓는점 사이의 온도(0℃~100℃)
// 화씨 : 물의 어는점을 32℉, 끓는점 212℉
f(섭씨온도) = (섭씨온도*1.8)+32 = y

(2) 함수 - 예제

- 복습용도로 한번 더 풀어보기
1. 메소드를 선언하고 호출하는 예제
public class MethodExample {
	public static int add(int a, int b) {
		return a+b;
	}
    public static void main(String[] args) {
		int result = add(5,3);
		System.out.println("Result: " + result);
	}
}
2. 메소드명이 같아도 매개변수가 서로 다르며 합을 구하는 예제
public class OverloadingExample {
	public static int add(int a, int b) {
		return a+b;
	}
	public static double add(double a, double b) {
		return a+b;
	}
    public static void main(String[] args) {
		int result1 = add(5,3);
		double result2 = add(2.5, 1.5);
		System.out.println("Result1: " + result1);
		System.out.println("Result2: " + result2);
	}
}
3. Square 값을 구하는 예제
public class SquareExample {
	public static int square(int num) {
		return num * num;
	}
    public static void main(String[] args) {
		int result = square(4);
		System.out.println("Square: " + result);
	}
}
4. 문자열 길이를 구하는 예제
public class StringLengthExample {
	public static int getStringLength(String text) {
		return text.length();
	}
	public static void main(String[] args) {
		String message = "Hello Java!";
		int length = getStringLength(message);
		System.out.println("Length: " + length);
    }
}
5. 배열의 합을 구하는 예제
public class ArraySumExample {
	public static int getArraySum(int[] arr) {
		int sum=0;
		for(int num : arr) {
			sum += num;
		}
		return sum;
	}
    public static void main(String[] args) {
		int[] numbers = {1,2,3,4,5};
		int sum = getArraySum(numbers);
		System.out.println("Sum: " + sum);
	}
}
6. 최댓값을 구하는 예제
public class MaxValueExample {
	public static int getMaxValue(int[] arr) {
		int max = arr[0];
		for(int num : arr) {
			if(num > max) {
				max = num;
			}
		}
		return max;
	}
    public static void main(String[] args) {
		int[] numbers = {14,6,23,8,31};
		int max = getMaxValue(numbers);
		System.out.println("Max value: " + max);
	}
}
7. 홀수인지 짝수인지 구하는 예제
public class EvenOddExample {
	public static boolean isEven(int num) {
		return num % 2 == 0;
	}
    public static void main(String[] args) {
		int number = 7;
		if(isEven(number)) {
			System.out.println(number + " is even.");
		} else {
			System.out.println(number + " is odd.");
		}
	}
}
8. 소수 구하기
public class PrimeNumberExample {
	public static boolean isPrime(int num) {
		if(num <= 1) {
			return false;
		}
		for(int i=2; i<= Math.sqrt(num); i++) {
			if(num % i == 0) {
				return false;
			}
		}
		return true;
	}
    public static void main(String[] args) {
		int number = 17;
		if(isPrime(number)) {
			System.out.println(number + " is a prime number");
		} else {
			System.out.println(number + " is not a prime number");
		}
	}
}

(3) 메소드

  • 객체지향언어로 사용됨.
  • 종류: 클래스 메소드, 인스턴스 메소드
    • 클래스(전역) 메소드: static이 붙은 메소드
    • 인스턴스(지역) 메소드: static이 붙지 않음
1. 클래스 메소드 선언부 구현방법과 실제 구현한 코드
public static int sum(int a, int b) {
	int sum = a+b;
    return sum;
}
  • 매개변수: 메소드를 실행시킬때 필요한 데이터를 기술.
  • 리턴될 값은 해당 메소드가 실행. 실행결과로 생성된 데이터를 의미함.
  • 메소드명 앞에 있는 리턴될 자료형은 메소드가 실행된 후 생성된 데이터의 자료형으로 기술.
  • 리턴될 자료형이 없다 > void, 리턴될 값: return
  • 다시 말해서, return 리턴값은 함수의 실행이 끝나고 남은 결과를 의미함.
  • 오버로드: 메소드명은 같지만 매개변수를 서로 다르게 하는 것.

1) 재귀호출

  • 메소드가 호출되면 메소드 정의부로 이동해 위에서 아래로 순서대로 실행.
  • 이어서 실행이 종료되면 이전에 호출한 코드부분으로 복귀

2) 무한 루프

  • 프로그램이 종료되지 않고 계속 반복하는 것

(4) 메소드: 예제

- 복습용도로 남겨둘 것
1. 사칙연산 가능한 메소드를 min mul div 메소드를 사용하여 
프로그램으로 만들어 보자.
2.System.out.println(sum(sum(1,1),sum(2,1));의 결과 값은 무엇인가? 5
public class Quiz1 {
	public static int sum(int a, int b) {
		return a+b;
	}
	public static int sub(int a, int b) {
		return a-b;
	}
	
	public static int mul(int a, int b) {
		return a*b;
	}
	
	public static int div(int a, int b) {
		return a/b;
	}
	
	public static void main(String[] args) {
		int a = sum(3,5);
		int b = a + sum(3,6);
		System.out.println(mul(a,b));
		System.out.println(div(a,b));

		System.out.println(sum(sum(1,1), sum(2,1)));
	}

}

3. 매개변수와 리턴 값이 없는 함수를 이용해서 “안녕하세요” 
라는 내용을 출력하는 함수 hello를 반복하는 함수
public class Quiz3 {
	public static void hello() {
		System.out.println("안녕하세요");		
	}

	public static void main(String[] args) {
		for(int i=1; i<=3; i++) {
			hello();
		}
		
	}

}
4. 입력받은 숫자가 7의 배수인지 아닌지 true, false값을 리턴하는 메소드를 구현
import java.util.Scanner;

public class Quiz4 {
	public static boolean multiple(int num) {
		if(num % 7 == 0) {
			return true;
		}
		return false;
	}
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.print("입력받을 숫자를 입력해주세요> ");
		int input = Integer.parseInt(scanner.nextLine());
		boolean result = multiple(input);
		System.out.println(input + "은 7의 배수일까요?" + result);
		
	}
}
-------------------------------------------------------------------
(230902 기준 새로운 코드 작성)
public static boolean isMul(int num) {
		return num % 7 == 0;
	}

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.print("입력할 숫자를 입력해주세요> ");
		int num = Integer.parseInt(scanner.nextLine());
		System.out.println(num + "은 7의 배수가 맞나요? " + isMul(num));				
        }
}
---------------------------------------------------------------------
5. 문자열과 숫자를 입력받아 해당문자열을 숫자만큼 반복 출력하는 메소드
import java.util.Scanner;

public class Quiz5 {
	public static void hello() {
		System.out.println("안녕하세요");
	}
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.print("반복할 숫자를 입력해주세요> ");
		int input = Integer.parseInt(scanner.nextLine());
		for(int i=1; i<=input; i++) {
			hello();
		}

	}

}
6. 두 사이 수의 합을 구하는 함수
public class Quiz6 {
	public static int sumAll(int a, int b) {
		int sum = 0;
		if(a>b) {
			int temp;
			temp = a;
			a = b;
			b = temp;
		}
		for (int i=a; i<=b; i++) {
			sum = sum + i;
		}
		return sum;
	}

	public static void main(String[] args) {
		int a = 5;
		int b = 2;
		System.out.println("두 숫자 사이의 합은 " + sumAll(a,b));

	}

}
7. 메소드란 무엇인가, 그리고 두 부분으로 나눠라.
- 메소드는 객체 지향 언어 프로그래밍에서 사용되는 메소드이다.
- 메소드는 클래스 메소드와 인스턴스 메소드가 있다.

8. 메소드 종류 2가지를 기술하시오.
- 클래스 메소드는 static 정적 메소드가 붙어 있는 메소드이다.
- 인스턴스 메소드는 static 정적 메소드가 붙어 있지 않은 메소드이다.

9. 전역과 지역의 의미?
- 전역은 전체 클래스 및 변수를 사용할 수 있다.
- 지역은 특정 클래스 및 변수를 사용할 수 있다.

10. 메소드 이름 용도는? 매개변수 용도는? return용도?
- 메소드 이름은 메소드 이름을 식별하기 위한 용도이다.
- 매개변수 용도는 실제 데이터 값을 넣기 위한 용도이다.
- return용도는 실행된 이후 남는 결과값을 리턴하는 용도이다.

11. 리턴될 자료형의 자리에 올 수 있는 키워드를 기술하고 설명하시오.
- 기본 자료형(int, double, boolean)

12. 리턴될 자료형이 없다면 무엇을 선언하는가?
- void를 선언한다

13. 오버로드와 오버라이딩의 차이는 무엇인가?
- 오버로드는 메소드명은 같지만 매개변수가 서로 다른 값을 가지는 것이다.
- 오버라이딩은 부모 클래스로부터 상속받은 클래스를 다시 재정의하는 것

14. 함수와 메소드의 차이는 무엇인가?
- 함수는 복잡한 코드를 미리 만들어놓고 필요할때 사용한다.
- 메소드는 객체지향 프로그래밍 언어에서 사용되는 메소드이다.

15. 재귀호출이란 무엇인가? 무한루프란?
- 재귀호출은 메소드가 호출되면 메소드 정의부로 이동해 위에서 아래로 순서대로 진행한다.
- 무한루프는 프로그램이 종료되지 않고 계속 반복하는 것을 말함.

16. 지역변수 사용범위에 대해 설명하시오.
지역변수는 메인 메소드 중괄호 블록 안에 사용된다.

2. 메소드로 은행 프로그램 구현

import com.human.test2.BankArray;

public class PlayBank {
	// 100명의 id, pw, account가 필요하여 배열 사용
	public static String id[] = new String[100];
	public static String pw[] = new String[100];
	public static double account[] = new double[100];
	
	// 사용자 입력시 사용하는 변수들
	public static java.util.Scanner sc = new java.util.Scanner(System.in);
	public static String inputId = null;
	public static String inputPw = null;
	public static double inputAccount = 0;
	
	// 운영시 필요한 변수들
	public static int totalUserCount = 0;
	// 로그인 관련 변수들
	public static final int LOGIN_LOG_OFF = 0; // 로그오프
	public static final int LOGIN_NORMAL_USER = 1; // 일반 사용자
	public static final int LOGIN_ADMIN_USER = 2; // 관리자
	
	// 현재 로그인 상태 저장 처음은 로그오프상태
	public static int loginState = PlayBank.LOGIN_LOG_OFF;
	public static int loginIndex = -1;
	
	// 관리자 정보
	public static String adminId = "admin";
	public static String adminPw = "1111";
	
	// 은행 초기데이터 3명의 계좌정보 입력
	public static void init() {
		id[0] = "user1"; id[1] = "user2"; id[2] = "user3";
		pw[0] = "user1"; pw[1] = "user2"; pw[2] = "user3";
		account[0] = 1000; account[1] = 2000; account[2] = 3000;
	}
	
	// 사용자나 관리자로 로그인하기
	public static void login() {
		while(loginState == PlayBank.LOGIN_LOG_OFF) {
			System.out.println("아이디와 pw를 입력해주세요");
			System.out.print("id> ");
			inputId = sc.nextLine();
			System.out.print("pw> ");
			inputPw = sc.nextLine();
			// 일반 사용자 로그인
			boolean isFindId = false;
			for(int i=0; i<totalUserCount; i++) {
				if(id[i].equals(inputId)) {
					if(pw[i].equals(inputPw)) {
						System.out.println(id[i] + "님 로그인 하였습니다.");
						loginState = PlayBank.LOGIN_NORMAL_USER;
						loginIndex = i;
					} else {
						System.out.println("잘못된 패스워드를 입력하였습니다.");
					}
					isFindId = true;
					break;
				}
			}
			if(!isFindId) {
				if(adminId.equals(inputId) && adminPw.equals(inputPw)) {
					System.out.println("관리자로 로그인 하였습니다");
					loginState = PlayBank.LOGIN_ADMIN_USER;
				} else {
					System.out.println(inputId + "는 존재하지 않습니다.");
				}
			}
		}
	}
	// 사용자가 사용할 메뉴
	public static void userMenu() {
		boolean isUseMenu = true;
		while(isUseMenu) {
			System.out.println("1. 입금 | 2. 출금 | 3. 잔액 조회 | 4. 종료 입력");
			switch(sc.nextLine()) {
			case "1":
				System.out.print("입금액 입력> ");
				inputAccount = Double.parseDouble(sc.nextLine());
				account[PlayBank.loginIndex] += inputAccount;
				System.out.println(id[PlayBank.loginIndex] + "님 잔액:" + account[PlayBank.loginIndex]);
				break;
			case "2":
				System.out.print("출금액 입력> ");
				inputAccount = Double.parseDouble(sc.nextLine());
				account[BankArray.loginUserIndex] -= inputAccount;
				System.out.println(id[PlayBank.loginIndex] + "님 잔액:" + account[PlayBank.loginIndex]);
				break;
			case "3":
				System.out.println("잔액 조회>");
				System.out.println(id[PlayBank.loginIndex] + "님 잔액:" + account[PlayBank.loginIndex]);
				break;
			case "4":
				System.out.println("사용자 메뉴 종료");
				PlayBank.loginState = PlayBank.LOGIN_LOG_OFF;
				isUseMenu = false;
				break;
			}
		}
	}

	// 관리자가 사용할 메뉴
	public static void adminMenu() {
		System.out.println("관리자");
		boolean isUseMenu = true;
		while(isUseMenu) {
			System.out.println("1. 계정 추가 | 2. 계정 삭제 | 3. id변경 | 4. 모든 사용자 출력 | 5. 종료 입력");
			switch(sc.nextLine()) {
			case "1":
				System.out.print("추가할 아이디 입력> ");
				inputId = sc.nextLine();
				System.out.print("추가할 암호 입력> ");
				inputPw = sc.nextLine();
				id[PlayBank.totalUserCount] = inputId;
				pw[PlayBank.totalUserCount] = inputPw;
				account[PlayBank.totalUserCount] = 100;
				System.out.println(id[PlayBank.totalUserCount] + "계정 생성");
				PlayBank.totalUserCount++;
				break;
			case "2":
				System.out.print("삭제할 아이디 입력> ");
				inputId = sc.nextLine();
				int findIndex = PlayBank.totalUserCount;
				for(int i=0; i<PlayBank.totalUserCount; i++) {
					if(id[i].equals(inputId)) {
						findIndex = i;
					}
				}
				for(int i=findIndex; i<PlayBank.totalUserCount; i++) {
					id[i] = id[i + 1];
					pw[i] = pw[i + 1];
					account[i] = account[i + 1];
				}
				PlayBank.totalUserCount--;
				break;
			case "3":
				System.out.print("변경할 아이디 입력> ");
				inputId = sc.nextLine();
				for(int i=0; i<PlayBank.totalUserCount; i++) {
					if(id[i].equals(inputId)) {
						System.out.print("변경할 아이디> ");
						id[i] = sc.nextLine();
						System.out.print("변경할 암호> ");
						pw[i] = sc.nextLine();
						System.out.print("변경할 account> ");
						account[i] = Double.parseDouble(sc.nextLine());
					}
				}
				break;
			case "4":
				System.out.println("출력 시작");
				for(int i=0; i<PlayBank.totalUserCount; i++) {
					System.out.print(i + "번째 아이디> " + id[i]);
					System.out.print(" pw> " + pw);
					System.out.println(" account> " + account[i]);
				}
				System.out.println("모두 출력");
				break;
			case "5":
				System.out.println("관리자 메뉴 종료");
				PlayBank.loginState = PlayBank.LOGIN_LOG_OFF;
				isUseMenu = false;
				break;
			}
		}
		}
		
	
	// 은행프로그램 시작 메소드
	public static void playBank() {
		boolean isUseMain = true;
		while(isUseMain) {
			// 사용자 // 로그오프 // 관리자
			login();
			// 일반유저나 관리자로 로그인 한 상태
			switch(loginState) {
			case PlayBank.LOGIN_LOG_OFF:
				break;
			case PlayBank.LOGIN_NORMAL_USER:
				userMenu();
				break;
			case PlayBank.LOGIN_ADMIN_USER:
				adminMenu();
				break;
			default:
				break;
			}
			System.out.print("새로 시작하시겠습니까? true or false");
			isUseMain = Boolean.parseBoolean(sc.nextLine());
		}
	}
	
	public static void main(String[] args) {
		init();
		playBank();
		System.out.println("프로그램 종료");

	}

}

3. 메소드에 매개변수 넣기

(1) 매개변수 넣기

  • 리턴값이 없는 메소드 코드
  • 해당 코드 실행시 스택 메모리가 들어가는 것을 볼 수 있음.

<설명>

  • 메인메소드에 a가 5로 선언되어 function1을 호출함.
  • function1은 a를 10으로 선언 후 a를 1씩 증가하여 function1 메모리에는 11이 들어간다.
  • 하지만, 메인메소드에는 두번이 호출되고 난 후 스택 영역에서 사라지기에 메인메소드에는 들어가지 않는다.
  • 메인메소드의 a를 1씩 증가하면 5에서 6. 6에서 7로 변경.

(2) 예제코드 확인 및 설명

  • function3 메소드에서 r=10이 11과 더해진 후 r 변수에 대입되었다. 즉, 기존 데이터 r값 10이 사라지고 11이 추가됨.
    • r값은 21. 21값으로 리턴되었다.
  • 메인 메소드에서 function3 리턴값이 int타입의 a변수에 집어 넣음.
  • a를 출력하고 a를 1씩 증가한다면 22

  • function4 메소드에 int타입의 a와 b를 더하면 rValue값으로 대입된다.
  • 메인 메소드에서 function(5,3)을 대입하면 8, function(1,2)를 대입하면 3. 두 함수를 더하면 11값이 나온다.

  • 참조 자료형을 전달하면 매개변수 주소로 전송하는 코드
  • function5 메소드에 a배열의 인덱스0번 값은 10
  • 메인 메소드의 arr 배열 값은 1,2
  • arr변수를 function5 메소드에 대입하면 배열에 10, 2가 출력

  • 먼저 그림 그려본 후 설명과 일치하면 넘어가기.
  • 이해가지 않으면 설명보면서 참고

  • function6 메소드 설명
    • a 데이터주소: 0x01,
    • rValue도 a 데이터주소 복사하여 0x01
  • function7 메소드 설명
    • a 데이터주소 : 0x01
    • rValue는 new 연산자를 사용했기에 0x02
  • main 메소드 설명
    • arr은 0x01
    • rArr은 0x02
  1. 메인 메소드에서 arr배열 값 1,2 가 있음.

  2. arr주소는 0x01이라고 하였는데 0번 인덱스에 1을 넣고 1번 인덱스에 2번을 넣는다

  3. 이 arr을 function6에 대입한다.

  4. function6으로 가서 arr주소값을 a에 넣는다.

  5. a 주소값을 rValue에 넣는다. 그러면 rValue는 0x01이다.

  6. rValue[0] = 11; 즉, 0x01의 0번 인덱스 값을 1에서 11로 변경된다.

  7. a[1] = 12; 즉, a 데이터 주소값이 0x01이기 때문에 1번 인덱스 값이 2에서 12로 변경된다.

  8. function6에서 rValue의 데이터주소값을 리턴한다.

  9. 화면에 출력하면 0x01의 arr[0] = 11; arr[1] = 12;


  1. arr데이터 주소값 0x01의 function7을 rArr 배열 데이터 주소를 대입하기 전에 먼저 호출한다.

  2. a배열의 크기를 new연산자를 이용하여 새 데이터 주소를 할당받았다. 그러면 0x01이 아닌 0x02가 됨. 0x02를 rValue에 대입.

  3. rValue[0] = 13; 함수7의 rValue 0번 인덱스 값이 13이 주어지면서 0x02 0번 인덱스에 13을 추가한다.
    (주의: new 연산자를 사용했기에 밑에 코드는 0x01이 아닌 0x02 데이터주소값을 가진다)

  4. a[1]=14; 함수7의 0x01의 a배열 인덱스값이 14가 주어지면서 12에서 14로 변경되었다.

  5. rValue[1] = a[1]; a[1]값은 14이기에 0x01의 rValue의 1번인덱스는 14가 된다.
  6. rValue 0x02를 리턴한다.

  7. 0x02의 rValue를 rArr 데이터주소에 넣는다. 그러면 rArr은 0x02가 된다.

  8. 화면에 출력시 0x01의 0번 인덱스: 11, 1번 인덱스: 14

  9. 0x02의 0번 인덱스 : 13, 1번 인덱스: 12

  1. 0x02의 rArr의 1번 인덱스 값이 9이다.
  2. 화면에 출력시
    0x01) [0]: 11, [1]: 14
    0x02) [0]: 13, [1]: 9

  1. 메인메소드에 h는 new연산자로 인해 새 human 객체가 생성되면서 데이터주소값은 0x01이 된다.

  2. h변수를 function8에 대입한 데이터주소값을 rH에 넣는다.

  3. 함수8에서 h의 0x01데이터 주소값을 rHuman변수에 집어 넣는다.

4.rHuman 변수에 인스턴스를 사용하여 나이가 31이라고 한다면 Human객체의 기존 나이 정보가 삭제되고 새 데이터 값이 출력됨.

  1. 메인메소드에 인스턴스 변수를 사용하여 나이를 50이라고 하면 31이 아닌 50이 출력.

  1. Human 객체를 생성하여 데이터값들을 생성하였다. 그리고 human클래스의 h변수에 대입하였음. h1 데이터 주소는 0x01이다.

  2. rH변수를 새로 선언하였음. 그리고 h변수를 function9에 집어넣고 호출함.

  3. function9에서 human객체를 new연산자로 새롭게 생성하여 새 데이터를 삽입하고 rHuman에 집어넣었다. 즉, rH는 0x02가 되었음.

  4. rh변수의 나이 데이터를 32, h변수 나이 데이터를 33이 선언되면 기존 데이터는 날라가고 새 데이터가 출력

  5. 0x02의 rHuman을 리턴한다. 그리고 rH의 나이 데이터를 50으로 변경하면 기존 데이터 32가 삭제되고 50이 출력.
profile
IT 개발자가 되기 위한 기록

0개의 댓글