출처: Medium 오늘 우리는 은행 시스템을 위한 간단한 Java 애플리케이션을 개발할 것입니다. 이는 Java 프로그램에서 OOP 개념이 어떻게 사용되는지 더 잘 이해하는 데 도움이 될 것입니다. 우선, 컴퓨터에 Java 환경(가급적 Java 11)이 설치되어 있어야 합니다. 다음으로 콘솔 애플리케이션의 기능에 대한 자세한 설명부터 시작하겠습니다. 기능의:
- 계정을 만드세요.
- 출구를 입력하십시오;
- 최근 5건의 거래 표시
- 현금 보증금;
- 현재 사용자 정보를 표시합니다.
- 계승;
- 다형성;
- 캡슐화.
응용 프로그램 개발
Eclipse 또는 IntelliJ IDEA에서 새로운 Java 프로젝트를 만들어 보겠습니다. SavingsAccount 라는 새 인터페이스를 정의해 보겠습니다 .public interface SavingsAccount {
void deposit(double amount, Date date);
}
나는 예금 메소드를 호스팅하는 인터페이스를 구현했습니다 . 나는 당좌 예금 계좌에 돈을 추가할 때마다 이 방법을 호출합니다. 여기에 사용된 OOP 개념은 다형성 (인터페이스의 메서드에는 본문이 없음)입니다. 이 메서드의 구현은 동일한 이름과 매개 변수를 가진 메서드를 재정의하여 Customer 클래스 에서 찾을 수 있습니다 . 이렇게 하면 하위 클래스의 상위 인터페이스에서 메서드를 재정의할 수 있습니다. 그런 다음 당좌 예금 계좌에 돈을 추가할 고객이 필요합니다. 하지만 먼저 Customer 클래스를 정의해 보겠습니다 .
public class Customer extends Person implements SavingsAccount {
private String username;
private String password;
private double balance;
private ArrayList<String> transactions = new ArrayList<>(5);
public Customer(String firstName, String lastName, String address, String phone, String username, String password, double balance, ArrayList<String> transactions, Date date) {
super(firstName, lastName, address, phone);
this.username = username;
this.password = password;
this.balance = balance;
addTransaction(String.format("Initial deposit - " + NumberFormat.getCurrencyInstance().format(balance) + " as on " + "%1$tD" + " at " + "%1$tT.", date));
}
private void addTransaction(String message) {
transactions.add(0, message);
if (transactions.size() > 5) {
transactions.remove(5);
transactions.trimToSize();
}
}
//Getter Setter
public ArrayList<String> getTransactions() {
return transactions;
}
@Override
public void deposit(double amount, Date date) {
balance += amount;
addTransaction(String.format(NumberFormat.getCurrencyInstance().format(amount) + " credited to your account. Balance - " + NumberFormat.getCurrencyInstance().format(balance) + " as on " + "%1$tD" + " at " + "%1$tT.", date));
}
@Override
public String toString() {
return "Customer{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", balance=" + balance +
", transactions=" + transactions +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
if (Double.compare(customer.getBalance(), getBalance()) != 0) return false;
if (getUsername() != null ? !getUsername().equals(customer.getUsername()) : customer.getUsername() != null)
return false;
if (getPassword() != null ? !getPassword().equals(customer.getPassword()) : customer.getPassword() != null)
return false;
return getTransactions() != null ? getTransactions().equals(customer.getTransactions()) : customer.getTransactions() == null;
}
@Override
public int hashCode() {
int result;
long temp;
result = getUsername() != null ? getUsername().hashCode() : 0;
result = 31 * result + (getPassword() != null ? getPassword().hashCode() : 0);
temp = Double.doubleToLongBits(getBalance());
result = 31 * result + (int) (temp ^ (temp >>> 32));
result = 31 * result + (getTransactions() != null ? getTransactions().hashCode() : 0);
return result;
}
여기서 사용된 OOP 개념은 상속 입니다 . Customer 클래스는 Person 클래스 로부터 속성을 받습니다 . 즉, Person 클래스의 거의 모든 속성이 상속되고 부모-자식 관계가 Person 에서 Customer 로 표시됩니다 . 이제 두 클래스의 모든 속성을 포함하고 상속된 속성을 지정하기 위해 수퍼 생성자 키워드를 추가하는 생성자가 필요합니다. SavingsAccount 인터페이스를 구현할 때 Customer 클래스 의 예금 메소드를 재정의해야 합니다 . 이를 위해 이 클래스에 메서드 구현을 작성합니다. 또한 마지막 5개의 트랜잭션을 표시하도록 트랜잭션 목록이 초기화됩니다. 생성자는 변경 날짜와 완료된 트랜잭션을 표시하는 addTransaction 메소드를 호출합니다.
private void addTransaction(String message) {
transactions.add(0, message);
if (transactions.size() > 5) {
transactions.remove(5);
transactions.trimToSize();
}
}
이제 부모 클래스인 Person 에 대해 이야기해보자 .
public class Person {
private String firstName;
private String lastName;
private String address;
private String phone;
public Person() {}
public Person(String firstName, String lastName, String address, String phone) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.phone = phone;
}
//Getters Setters
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", address='" + address + '\'' +
", phone='" + phone + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (getFirstName() != null ? !getFirstName().equals(person.getFirstName()) : person.getFirstName() != null)
return false;
if (getLastName() != null ? !getLastName().equals(person.getLastName()) : person.getLastName() != null)
return false;
if (getAddress() != null ? !getAddress().equals(person.getAddress()) : person.getAddress() != null)
return false;
return getPhone() != null ? getPhone().equals(person.getPhone()) : person.getPhone() == null;
}
@Override
public int hashCode() {
int result = getFirstName() != null ? getFirstName().hashCode() : 0;
result = 31 * result + (getLastName() != null ? getLastName().hashCode() : 0);
result = 31 * result + (getAddress() != null ? getAddress().hashCode() : 0);
result = 31 * result + (getPhone() != null ? getPhone().hashCode() : 0);
return result;
}
Person 클래스 에서는 각 속성에 private 접근 수정자를 적용하여 캡슐화 개념을 사용했습니다 . Java의 캡슐화는 이 데이터에 대해 작동하는 메소드를 단일 단위로 결합하는 메커니즘으로 정의할 수 있습니다. 기본적으로 Person 클래스의 데이터는 이 클래스에서만 사용할 수 있으며 다른 클래스나 패키지에서는 사용할 수 없습니다. 마지막으로 Bank 라는 메인 클래스가 있습니다 . 이는 애플리케이션을 실행하고 모든 클래스의 기능과 상호 작용하는 주요 클래스입니다.
public class Bank {
private static double amount = 0;
Map<String, Customer> customerMap;
Bank() {
customerMap = new HashMap<String, Customer>();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Customer customer;
Bank bank = new Bank();
int choice;
outer:
while (true) {
System.out.println("\n-------------------");
System.out.println("BANK OF JAVA");
System.out.println("-------------------\n");
System.out.println("1. Registrar cont.");
System.out.println("2. Login.");
System.out.println("3. Exit.");
System.out.print("\nEnter your choice : ");
choice = sc.nextInt();
sc.nextLine();
switch (choice) {
case 1:
System.out.print("Enter First Name : ");
String firstName = sc.nextLine();
System.out.print("Enter Last Name : ");
String lastName = sc.nextLine();
System.out.print("Enter Address : ");
String address = sc.nextLine();
System.out.print("Enter contact number : ");
String phone = sc.nextLine();
System.out.println("Set Username : ");
String username = sc.next();
while (bank.customerMap.containsKey(username)) {
System.out.println("Username already exists. Set again : ");
username = sc.next();
}
System.out.println("Set a password:");
String password = sc.next();
sc.nextLine();
customer = new Customer(firstName, lastName, address, phone, username, password, new Date());
bank.customerMap.put(username, customer);
break;
case 2:
System.out.println("Enter username : ");
username = sc.next();
sc.nextLine();
System.out.println("Enter password : ");
password = sc.next();
sc.nextLine();
if (bank.customerMap.containsKey(username)) {
customer = bank.customerMap.get(username);
if (customer.getPassword().equals(password)) {
while (true) {
System.out.println("\n-------------------");
System.out.println("W E L C O M E");
System.out.println("-------------------\n");
System.out.println("1. Deposit.");
System.out.println("2. Transfer.");
System.out.println("3. Last 5 transactions.");
System.out.println("4. User information.");
System.out.println("5. Log out.");
System.out.print("\nEnter your choice : ");
choice = sc.nextInt();
sc.nextLine();
switch (choice) {
case 1:
System.out.print("Enter amount : ");
while (!sc.hasNextDouble()) {
System.out.println("Invalid amount. Enter again :");
sc.nextLine();
}
amount = sc.nextDouble();
sc.nextLine();
customer.deposit(amount, new Date());
break;
case 2:
System.out.print("Enter beneficiary username : ");
username = sc.next();
sc.nextLine();
System.out.println("Enter amount : ");
while (!sc.hasNextDouble()) {
System.out.println("Invalid amount. Enter again :");
sc.nextLine();
}
amount = sc.nextDouble();
sc.nextLine();
if (amount > 300) {
System.out.println("Transfer limit exceeded. Contact bank manager.");
break;
}
if (bank.customerMap.containsKey(username)) {
Customer payee = bank.customerMap.get(username); //Todo: check
payee.deposit(amount, new Date());
customer.withdraw(amount, new Date());
} else {
System.out.println("Username doesn't exist.");
}
break;
case 3:
for (String transactions : customer.getTransactions()) {
System.out.println(transactions);
}
break;
case 4:
System.out.println("Titularul de cont cu numele: " + customer.getFirstName());
System.out.println("Titularul de cont cu prenumele : " + customer.getLastName());
System.out.println("Titularul de cont cu numele de utilizator : " + customer.getUsername());
System.out.println("Titularul de cont cu addresa : " + customer.getAddress());
System.out.println("Titularul de cont cu numarul de telefon : " + customer.getPhone());
break;
case 5:
continue outer;
default:
System.out.println("Wrong choice !");
}
}
} else {
System.out.println("Wrong username/password.");
}
} else {
System.out.println("Wrong username/password.");
}
break;
case 3:
System.out.println("\nThank you for choosing Bank Of Java.");
System.exit(1);
break;
default:
System.out.println("Wrong choice !");
}}}}
java.util 라이브러리를 사용하여 Scanner를 호출하여 키보드를 읽습니다. Bank 라는 정의를 통해 Customer 개체를 캐스팅하여 Bank() 유형의 새 개체를 만듭니다 . 잠시 후 시작 메뉴가 표시됩니다. nextLine 을 사용하면 키보드에서 추가된 숫자를 읽어옵니다. 아래에는 클라이언트 데이터인 map을 저장하는 새로운 생성자가 있습니다 . Map.put은 고객 데이터를 저장하거나 업데이트하는 데 사용됩니다. 고객 = 새 고객(이름, 성, 주소, 전화번호, 사용자 이름, 비밀번호, 새 날짜());
bank.customerMap.put(username, customer);
연결이 있으면 옵션이 포함된 새 메뉴가 표시됩니다. while 및 스위치를 사용하여 응용 프로그램 기능을 호출하면 동일한 접근 방식이 작동합니다 . 1단계: 현재 계좌에 돈을 추가합니다. 2단계: 최근 5개의 거래를 표시합니다. 3단계: 카드의 클라이언트 데이터를 콘솔로 출력합니다. 4단계: 메뉴를 닫습니다. 프로그램의 소스 코드는 여기에서 찾을 수 있습니다 . 이 예제가 Java에서 OOP 개념의 사용에 더 익숙해지는 데 도움이 되기를 바랍니다.
GO TO FULL VERSION