목표와 전체 소스 코드
만들고자 하는 프로그램
다음은 키보드로부터 계좌 정보를 입력받아 계좌를 관리하는 프로그램입니다. 계좌는 Account
객체로 생성되고 BankApplication에서 길이 100인 Account[ ] 배열로 관리됩니다. 실행 결과를
보고, Account와 BankApplication 클래스를 작성해보세요(키보드로 입력받을 때는 Scanner
의 nextLine ( ) 메소드를 사용).
객체는 공부했다. 그런데 Account[] 배열로 만들라 하니 전혀 감이 잡히지 않았다. 이것 때문에 고민하고 설계하는 데 투입한 시간이 절대적으로 많다. 그런 거 예제에서도 안 만들어 봤는데 바로 만들어 보라고 한다...
소스 코드
1. Account 클래스
package ch_06.practice._20;
public class Account {
private String accountNum;
private String name;
private int balance;
public void setAccountNum(String accountNum) {
this.accountNum = accountNum;
}
public void setName(String name) {
this.name = name;
}
public void setDeposit(String deposit) {
int depositInt = Integer.parseInt(deposit);
if (depositInt < 0) {
return;
}
balance += depositInt;
}
public void setWithdraw(String withdraw) {
int withdrawInt = Integer.parseInt(withdraw);
if (withdrawInt < 0) {
return;
}
balance -= withdrawInt;
if (balance < 0) {
balance += withdrawInt;
System.out.println("결과 : 잔액이 부족합니다.");
} else {
System.out.println("결과 : 출금이 성공되었습니다.");
}
}
public String getAccountNum() {
return accountNum;
}
public String getName() {
return name;
}
public int getBalance() {
return balance;
}
}
2. BankApplication 클래스 (실행 클래스)
package ch_06.practice._20;
import java.util.Scanner;
public class BankApplication {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Account[] account = new Account[100];
int numberOfAccounts = 0;
boolean stop = false;
while (!stop) {
System.out.println("---------------------------------------------");
System.out.println("1.계좌생성 | 2.계좌목록 | 3.예금 | 4.출금 | 5.종료");
System.out.println("---------------------------------------------");
System.out.print("선택 > ");
String input = scanner.nextLine();
System.out.println();
switch (input) {
case "1":
System.out.println("-------");
System.out.println("계좌생성");
System.out.println("-------");
System.out.print("계좌번호 : ");
String accountNumInput = scanner.nextLine();
System.out.print("계좌주 : ");
String nameInput = scanner.nextLine();
System.out.print("초기입금액 : ");
String depositInput = scanner.nextLine();
Account accountInfo = new Account();
accountInfo.setAccountNum(accountNumInput);
accountInfo.setName(nameInput);
accountInfo.setDeposit(depositInput);
account[numberOfAccounts] = accountInfo;
System.out.println("결과 : 계좌가 생성되었습니다.");
++numberOfAccounts;
break;
case "2":
System.out.println("-------");
System.out.println("계좌목록");
System.out.println("-------");
int i = 0;
while (account[i] != null) {
System.out.print(account[i].getAccountNum() + " ");
System.out.print(account[i].getName() + " ");
System.out.println(account[i].getBalance());
++i;
}
break;
case "3":
System.out.println("-------");
System.out.println("예금");
System.out.println("-------");
System.out.print("계좌번호 : ");
accountNumInput = scanner.nextLine();
System.out.print("예금액 : ");
depositInput = scanner.nextLine();
for (i = 0; i < account.length; i++) {
if (accountNumInput.equals(account[i].getAccountNum())) {
account[i].setDeposit(depositInput);
break;
}
}
break;
case "4":
System.out.println("-------");
System.out.println("출금");
System.out.println("-------");
System.out.print("계좌번호 : ");
accountNumInput = scanner.nextLine();
System.out.print("출금액 : ");
String withdraw = scanner.nextLine();
for (i = 0; i < account.length; i++) {
assert account[i] != null;
if (accountNumInput.equals(account[i].getAccountNum())) {
account[i].setWithdraw(withdraw);
break;
}
}
break;
case "5":
stop = true;
System.out.println("프로그램 종료");
}
}
}
}
세부 내용
Account.java
1. 필드 선언
public class Account {
private String accountNum;
private String name;
private int balance;
고객 데이터를 기록하는 field는 외부에서 호출하거나 임의로 변경되면 안 되기 때문에 private으로 보호한다. Setter를 이용해 초기값을 저장할 것이므로 생성자는 기본 생성자를 사용한다.
2. Setter와 Getter 메소드 선언
public void setAccountNum(String accountNum) {
this.accountNum = accountNum;
}
public void setName(String name) {
this.name = name;
}
public void setDeposit(String deposit) {
int depositInt = Integer.parseInt(deposit);
if (depositInt < 0) {
return;
}
balance += depositInt;
}
public void setWithdraw(String withdraw) {
int withdrawInt = Integer.parseInt(withdraw);
if (withdrawInt < 0) {
return;
}
balance -= withdrawInt;
if (balance < 0) {
balance += withdrawInt;
System.out.println("결과 : 잔액이 부족합니다.");
} else {
System.out.println("결과 : 출금이 성공되었습니다.");
}
}
public String getAccountNum() {
return accountNum;
}
public String getName() {
return name;
}
public int getBalance() {
return balance;
}
field값을 변경하고 보내 주기 위해 Setter와 Getter를 선언한다.
문제의 요구사항에는 없지만 입금액과 출금액을 마이너스 값으로 입력했을 때 잘못 변경되지 않도록 setDeposit 메소드와 setWithDraw 메소드로 방지했다. 이 두 method는 String 입력값을 받아 와 int로 변경 후, 양수 여부가 확인되면 balance 필드에 저장한다.
마찬가지로 문제의 요구사항에는 없지만 마이너스 통장이 아닌 이상 잔액 한도까지만 출금 가능하므로, 한도를 넘어 출금하려 하면 잔액 부족 메시지가 뜨도록 만들어 봤다.
BankApplication.java
1. 선언
import java.util.Scanner;
public class BankApplication {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Account[] account = new Account[100];
int numberOfAccounts = 0;
boolean stop = false;
Account 타입의 배열을 만드는 부분에서 골치를 많이 앓았다. 해당 내용은 다음 글의 문제 해결과정 부분에 따로 서술한다.
Scanner는 번호와 정보 입력에 쓰인다. numberOfAccounts는 바로 아래에서 쓰이므로, 거기서 설명한다. stop은 프로그램을 종료하기 위한 연산자다.
2. while 반복문과 계좌생성
while (!stop) {
System.out.println("---------------------------------------------");
System.out.println("1.계좌생성 | 2.계좌목록 | 3.예금 | 4.출금 | 5.종료");
System.out.println("---------------------------------------------");
System.out.print("선택 > ");
String input = scanner.nextLine();
System.out.println();
switch (input) {
case "1":
System.out.println("-------");
System.out.println("계좌생성");
System.out.println("-------");
System.out.print("계좌번호 : ");
String accountNumInput = scanner.nextLine();
System.out.print("계좌주 : ");
String nameInput = scanner.nextLine();
System.out.print("초기입금액 : ");
String depositInput = scanner.nextLine();
Account accountInfo = new Account();
accountInfo.setAccountNum(accountNumInput);
accountInfo.setName(nameInput);
accountInfo.setDeposit(depositInput);
account[numberOfAccounts] = accountInfo;
System.out.println("결과 : 계좌가 생성되었습니다.");
++numberOfAccounts;
break;
단순해 보이지만 가장 어려웠던 부분이다. 기본적으로 Scanner를 통해 1번을 입력하면 계좌 정보를 등록하게 되어 있다. 이 선택 번호는 int로 입력할 때 문제가 발생해 String으로 입력하게 했다. 역시 다음 글의 문제 해결과정 부분에서 설명한다.
Acccount[] 배열에 계좌를 따로 저장하는 방법이 어려워 시간을 가장 많이 소모했다. 결국 선택한 방식은 계좌 생성 메뉴에 들어갈 때마다 accountInfo 변수를 통해 객체를 새로 생성하고, Account 객체의 Setter를 통해 field에 값을 저장하게 한 뒤, 배열의 원소에 하나씩 대입하는 것이다. 현재 식은 비교적 단순해졌지만 시행착오를 많이 겪었으며, 올바른 방법을 찾아내기가 좀처럼 쉽지 않았다.
아래의 numberOfAccounts는 계좌를 생성할 때마다 1씩 증가하면서 계좌가 중복되지 않도록 한다. 길이 100의 배열에 하나씩 계좌 정보를 저장하기 위한 것이다.
해답에서는 각 번호를 선택하면 객체 내부의 다른 method들을 호출하는 방식으로 작성했는데, 그렇게 하는 것이라는 걸 해답을 보고서야 알았다. 훨씬 가독성이 좋고 연산 과정들을 private 접근 제한자로 보호할 수 있어 더욱 좋다. 내 방식은 전체 구조가 잘 보이지 않는다. 해답은 이번에도 if-else문을 썼는데, switch문이 읽기에는 더 나은 것 같다.
3. 계좌 목록과 입금
case "2":
System.out.println("-------");
System.out.println("계좌목록");
System.out.println("-------");
int i = 0;
while (account[i] != null) {
System.out.print(account[i].getAccountNum() + " ");
System.out.print(account[i].getName() + " ");
System.out.println(account[i].getBalance());
++i;
}
break;
case "3":
System.out.println("-------");
System.out.println("예금");
System.out.println("-------");
System.out.print("계좌번호 : ");
accountNumInput = scanner.nextLine();
System.out.print("예금액 : ");
depositInput = scanner.nextLine();
for (i = 0; i < account.length; i++) {
if (accountNumInput.equals(account[i].getAccountNum())) {
account[i].setDeposit(depositInput);
break;
}
}
break;
계좌 생성이 제대로 됐으면 이후부터는 쉽다. account 배열 원소들의 초기값이 지정되었기 때문이다. 계좌 목록은 while문을 이용해 현재 생성된 계좌를 모두 보여 주고, 생성되지 않은 계좌(null)는 보여주지 않게 되어 있다.
입금할 때도 계좌 생성 시와 마찬가지로 Setter를 통해 값을 입력하여 마이너스 값이 대입되지 않도록 한다. for문을 통해 입력한 계좌와 일치하는 계좌를 찾으면 바로 break를 작동시켜 작업량을 줄이게 했다.
4. 출금과 종료
case "4":
System.out.println("-------");
System.out.println("출금");
System.out.println("-------");
System.out.print("계좌번호 : ");
accountNumInput = scanner.nextLine();
System.out.print("출금액 : ");
String withdraw = scanner.nextLine();
for (i = 0; i < account.length; i++) {
assert account[i] != null;
if (accountNumInput.equals(account[i].getAccountNum())) {
account[i].setWithdraw(withdraw);
break;
}
}
break;
case "5":
stop = true;
System.out.println("프로그램 종료");
출금할 때도 마이너스를 입력하면 잔액이 변경되지 않고, 잔액 한도 이상으로 출금하면 출금 실패 메시지가 출력된다.
5번을 입력하면 프로그램을 종료한다.
글이 너무 길어져 발생한 문제와 해결과정은 다음 글에 포스팅한다.
'Development > Java' 카테고리의 다른 글
method overriding 과정에서 @Override annotation을 사용해야 하는 이유 (0) | 2023.03.29 |
---|---|
인터페이스의 객체지향적 특징 (0) | 2023.03.28 |
객체지향의 네 가지 특성 : 캡슐화, 추상화, 다형성, 상속성 (0) | 2023.03.28 |
(객체지향 기초) Java로 계좌 관리 프로그램 만들기(2) (0) | 2023.03.18 |
(배열 기초) Java로 점수 분석 프로그램 만들기 (0) | 2023.03.09 |