Giter VIP home page Giter VIP logo

study5's Introduction

👋 Hi, I’m @Heewon-Seo.
📫 How to reach me email me [email protected]
🖥 Here's my portfolio Portfolio

Leetcode Stats

Code Time

Profile Views

🐱 My GitHub Data

📦 152.7 kB Used in GitHub's Storage

🏆 0 Contributions in the Year 2024

🚫 Not Opted to Hire

📜 21 Public Repositories

🔑 3 Private Repositories

I'm a Night 🦉

🌞 Morning                19 commits          ██░░░░░░░░░░░░░░░░░░░░░░░   06.91 % 
🌆 Daytime                69 commits          ██████░░░░░░░░░░░░░░░░░░░   25.09 % 
🌃 Evening                113 commits         ██████████░░░░░░░░░░░░░░░   41.09 % 
🌙 Night                  74 commits          ███████░░░░░░░░░░░░░░░░░░   26.91 % 

📅 I'm Most Productive on Wednesday

Monday                   44 commits          ████░░░░░░░░░░░░░░░░░░░░░   16.00 % 
Tuesday                  41 commits          ████░░░░░░░░░░░░░░░░░░░░░   14.91 % 
Wednesday                47 commits          ████░░░░░░░░░░░░░░░░░░░░░   17.09 % 
Thursday                 40 commits          ████░░░░░░░░░░░░░░░░░░░░░   14.55 % 
Friday                   37 commits          ███░░░░░░░░░░░░░░░░░░░░░░   13.45 % 
Saturday                 27 commits          ██░░░░░░░░░░░░░░░░░░░░░░░   09.82 % 
Sunday                   39 commits          ████░░░░░░░░░░░░░░░░░░░░░   14.18 % 

📊 This Week I Spent My Time On

🕑︎ Time Zone: Asia/Seoul

💬 Programming Languages: 
JavaScript               7 hrs 59 mins       ██████████░░░░░░░░░░░░░░░   41.58 % 
Java                     5 hrs 19 mins       ███████░░░░░░░░░░░░░░░░░░   27.71 % 
SQL                      4 hrs 22 mins       ██████░░░░░░░░░░░░░░░░░░░   22.81 % 
XML                      1 hr 12 mins        ██░░░░░░░░░░░░░░░░░░░░░░░   06.26 % 
CSS                      8 mins              ░░░░░░░░░░░░░░░░░░░░░░░░░   00.77 % 

🔥 Editors: 
IntelliJ IDEA            14 hrs 49 mins      ███████████████████░░░░░░   77.19 % 
DataGrip                 4 hrs 22 mins       ██████░░░░░░░░░░░░░░░░░░░   22.81 % 

🐱‍💻 Projects: 
oss-api                  13 hrs 18 mins      █████████████████░░░░░░░░   69.25 % 
DataGripProjects         4 hrs 22 mins       ██████░░░░░░░░░░░░░░░░░░░   22.81 % 
batch                    35 mins             █░░░░░░░░░░░░░░░░░░░░░░░░   03.05 % 
oss-nxui                 23 mins             █░░░░░░░░░░░░░░░░░░░░░░░░   02.04 % 
ims-api                  14 mins             ░░░░░░░░░░░░░░░░░░░░░░░░░   01.26 % 

💻 Operating System: 
Mac                      19 hrs 12 mins      █████████████████████████   100.00 % 

I Mostly Code in Java

Java                     6 repos             ██████████░░░░░░░░░░░░░░░   40.00 % 
CSS                      2 repos             ███░░░░░░░░░░░░░░░░░░░░░░   13.33 % 
TypeScript               2 repos             ███░░░░░░░░░░░░░░░░░░░░░░   13.33 % 
JavaScript               2 repos             ███░░░░░░░░░░░░░░░░░░░░░░   13.33 % 
Astro                    1 repo              ██░░░░░░░░░░░░░░░░░░░░░░░   06.67 % 

Timeline

Lines of Code chart

Last Updated on 15/08/2024 18:34:39 UTC

study5's People

Contributors

heewon-seo avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Forkers

ggujin

study5's Issues

7/28 다형성 정리 - 남궁은

[JAVA]

다형성(polymorphism)이란?

다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미합니다

자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있습니다

다형성은 상속, 추상화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나입니다

참조 변수의 다형성

자바에서는 다형성을 위해 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하고 있습니다

이때 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 같거나 적어야 참조할 수 있습니다

다음 예제는 참조 변수의 다형성을 보여주는 예제입니다

예제

class Parent { ... }

class Child extends Parent { ... }

...

Parent pa = new Parent(); // 허용

Child ch = new Child();   // 허용

Parent pc = new Child();  // 허용

Child cp = new Parent();  // 오류 발생

특정 타입의 참조 변수로는 당연히 같은 타입의 인스턴스를 참조할 수 있습니다

참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수와 같기 때문입니다

그리고 부모 클래스 타입의 참조 변수로도 자식 클래스 타입의 인스턴스를 참조할 수 있습니다

참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 적기 때문입니다

하지만 반대의 경우인 자식 클래스 타입의 참조 변수로는 부모 클래스 타입의 인스턴스를 참조할 수 없습니다

참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 많기 때문입니다

클래스는 상속을 통해 확장될 수는 있어도 축소될 수는 없으므로, 자식 클래스에서 사용할 수 있는 멤버의 개수가 언제나 부모 클래스와 같거나 많게 됩니다


참조 변수의 타입 변환

자바에서는 참조 변수도 다음과 같은 조건에 따라 타입 변환을 할 수 있습니다

  1. 서로 상속 관계에 있는 클래스 사이에만 타입 변환을 할 수 있습니다

  2. 자식 클래스 타입에서 부모 클래스 타입으로의 타입 변환은 생략할 수 있습니다

  3. 하지만 부모 클래스 타입에서 자식 클래스 타입으로의 타입 변환은 반드시 명시해야 합니다

참조 변수의 타입 변환도 기본 타입의 타입 변환과 마찬가지로 타입 캐스트 연산자(())를 사용합니다

문법

(변환할 타입의 클래스 이름) 변환할 참조변수

다음 예제는 참조 변수의 타입 변환을 보여주는 예제입니다

예제

class Parent { ... }

class Child extends Parent { ... }

class Brother extends Parent { ... }

...

Parent pa01 = null;

Child ch = new Child();

Parent pa02 = new Parent();

Brother br = null;

pa01 = ch;          // pa01 = (Parent)ch; 와 같으며, 타입 변환을 생략할 수 있음

br = (Brother)pa02; // 타입 변환을 생략할 수 없음

br = (Brother)ch;   // 직접적인 상속 관계가 아니므로, 오류 발생


instanceof 연산자

이러한 다형성으로 인해 런타임에 참조 변수가 실제로 참조하고 있는 인스턴스의 타입을 확인할 필요성이 생깁니다

자바에서는 instanceof 연산자를 제공하여, 참조 변수가 참조하고 있는 인스턴스의 실제 타입을 확인할 수 있도록 해줍니다

자바에서 instanceof 연산자는 다음과 같이 사용합니다

문법

참조변수 instanceof 클래스이름

왼쪽에 전달된 참조 변수가 실제로 참조하고 있는 인스턴스의 타입이 오른쪽에 전달된 클래스 타입이면 true를 반환하고, 아니면 false를 반환합니다

만약에 참조 변수가 null을 가리키고 있으면 false를 반환합니다

다음 예제는 참조 변수가 실제로 가리키고 있는 인스턴스의 타입을 instanceof 연산자로 확인하는 예제입니다

예제

class Parent { }

class Child extends Parent { }

class Brother extends Parent { }

public class Polymorphism01 {

public static void main(String[] args) {

Parent p = new Parent();

**System.out.**println(p instanceof Object); // true

**System.out.**println(p instanceof Parent); // true

**System.out.**println(p instanceof Child);  // false

**System.out.**println();

Parent c = new Child();

**System.out.**println(c instanceof Object); // true

**System.out.**println(c instanceof Parent); // true

**System.out.**println(c instanceof Child);  // true

****}

}

추상 클래스(abstract class)

자바에서는 하나 이상의 추상 메소드를 포함하는 클래스를 가리켜 추상 클래스(abstract class)라고 합니다

이러한 추상 클래스는 객체 지향 프로그래밍에서 중요한 특징인 다형성을 가지는 메소드의 집합을 정의할 수 있도록 해줍니다

즉, 반드시 사용되어야 하는 메소드를 추상 클래스에 추상 메소드로 선언해 놓으면, 이 클래스를 상속받는 모든 클래스에서는 이 추상 메소드를 반드시 재정의해야 합니다

자바에서 추상 클래스는 다음과 같은 문법으로 선언합니다

문법

abstract class 클래스이름 {

...

abstract 반환타입 메소드이름();

...

}

이러한 추상 클래스는 동작이 정의되어 있지 않은 추상 메소드를 포함하고 있으므로, 인스턴스를 생성할 수 없습니다

추상 클래스는 먼저 상속을 통해 자식 클래스를 만들고, 만든 자식 클래스에서 추상 클래스의 모든 추상 메소드를 오버라이딩하고 나서야 비로소 자식 클래스의 인스턴스를 생성할 수 있게 됩니다

추상 클래스는 추상 메소드를 포함하고 있다는 점을 제외하면, 일반 클래스와 모든 점이 같습니다.즉, 생성자와 필드, 일반 메소드도 포함할 수 있습니다

예제

abstract class Animal { abstract void cry(); }

class Cat extends Animal { void cry() { **System.out.**println("냐옹냐옹!"); } }

class Dog extends Animal { void cry() { **System.out.**println("멍멍!"); } }

public class Polymorphism02 {

public static void main(String[] args) {

****// Animal a = new Animal(); // 추상 클래스는 인스턴스를 생성할 수 없음.

Cat c = new Cat();

Dog d = new Dog();

****    c**.**cry();

****    d**.**cry();

****}

}

A클래스, B클래스, C클래스가 있다고 가정해봅시다. 여기서 각 클래스 안에는 각자의 필드와 메서드가 있을것이다. 추상클래스는 A클래스, B클래스, C클래스 간에 비슷한 필드와 메서드를 공통적으로 추출해 만들어진 클래스입니다

예를 들어 '키보드'라는 클래스가 있습니다. '키보드'를 만드는 제조사는 여러개입니다. A제조사, B제조사, C제조사는 각 제조사만의 스타일대로 키보드를 제작하고 소비자들에게 제품을 출시합니다. 여기서 A제조사는 키보드를 누를때 마다 불빛이 들어온다. B제조사는 키보드를 누를때 딸깍 거리는 소리가 납니다. C제조사는 키보드를 누를때 살짝만 눌러도 잘 눌립니다

각기 다른 특성을 지닌 세 키보드 간에도 공통적인 부분이 있습니다. 키보드를 눌러서 사용하는 것입니다. 이것은 모두 공통입니다. 즉 메서드가 공통적입니다. 그럼 이 메서드를 추출해서 추상클래스 안에 두면 됩니다

(키보드를 상속받아 탄생한,  A키보드, B키보드, C키보드)

다른 예로는 사람의 얼굴이 있습니다. 일반적으로 귀 2개, 눈 2개, 입 1개, 코 1개를 지니고있습니다

이는 모두 공통적인 변수입니다. 이 변수들을 추상클래스에 넣는 것입니다

실체클래스는 실체가 드러나는 클래스이고, 추상클래스는 실체 클래싀의 공통적인 부분을 추출하여 어느 정도 규격을 잡아놓은 추상적인 클래스입니다

실체클래스는 실체 객체를 생성할 정도의 구체성을 가지고 있는 반면, 추상클래스는 아직 메서드와 내용이 추상적이기 때문에 객체를 생성할 수 없게 만들었습니다

따라서 객체를 직접 생성할 수 있는 클래스를 실체클래스라고 하고, 실체클래스들의 공통적인 특성을 추출해서 선언한 클래스를 추상클래스라고 합니다. 여기서 추상클래스와 실체클래스는 상속적인 관계를 가지고 있습니다

1. 추상클래스란 실체클래스의 공통적인 부분(변수,메서드)를 추출해서 선언한 클래스

2. 추상클래스는 객체를 생성할 수 없음. 아직은 실체성이 없고 구체적이지 않기 때문

3. 추상클래스와 실체클래스는 상속관계

추상 메소드(abstract method)

추상 메소드(abstract method)란 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드를 의미합니다

자바에서 추상 메소드를 선언하여 사용하는 목적은 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함입니다

예를 들면 모듈처럼 중복되는 부분이나 공통적인 부분은 미리 다 만들어진 것을 사용하고, 이를 받아 사용하는 쪽에서는 자신에게 필요한 부분만을 재정의하여 사용함으로써 생산성이 향상되고 배포 등이 쉬워지기 때문입니다

이러한 추상 메소드는 선언부만이 존재하며, 구현부는 작성되어 있지 않습니다

바로 이 작성되어 있지 않은 구현부를 자식 클래스에서 오버라이딩하여 사용하는 것입니다

자바에서 추상 메소드는 다음과 같은 문법으로 선언합니다

문법

abstract 반환타입 메소드이름();

인터페이스(interface)란?

자식 클래스가 여러 부모 클래스를 상속받을 수 있다면, 다양한 동작을 수행할 수 있다는 장점을 가지게 될 것입니다

하지만 클래스를 이용하여 다중 상속을 할 경우 메소드 출처의 모호성 등 여러 가지 문제가 발생할 수 있어 자바에서는 클래스를 통한 다중 상속은 지원하지 않습니다

하지만 다중 상속의 이점을 버릴 수는 없기에 자바에서는 인터페이스라는 것을 통해 다중 상속을 지원하고 있습니다

인터페이스(interface)란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미합니다

자바에서 추상 클래스는 추상 메소드뿐만 아니라 생성자, 필드, 일반 메소드도 포함할 수 있습니다

하지만 인터페이스(interface)는 오로지 추상 메소드와 상수만을 포함할 수 있습니다


인터페이스의 선언

자바에서 인터페이스를 선언하는 방법은 클래스를 작성하는 방법과 같습니다

인터페이스를 선언할 때에는 접근 제어자와 함께 interface 키워드를 사용하면 됩니다

자바에서 인터페이스는 다음과 같이 선언합니다

문법

접근제어자 interface 인터페이스이름 {

public static final 타입 상수이름 = 값;

...

public abstract 메소드이름(매개변수목록);

...

}

단, 클래스와는 달리 인터페이스의 모든 필드는 public static final이어야 하며, 모든 메소드는 public abstract이어야 합니다

이 부분은 모든 인터페이스에 공통으로 적용되는 부분이므로 이 제어자는 생략할 수 있습니다

이렇게 생략된 제어자는 컴파일 시 자바 컴파일러가 자동으로 추가해 줍니다

인터페이스의 구현

인터페이스는 추상 클래스와 마찬가지로 자신이 직접 인스턴스를 생성할 수는 없습니다

따라서 인터페이스가 포함하고 있는 추상 메소드를 구현해 줄 클래스를 작성해야만 합니다

자바에서 인터페이스는 다음과 같은 문법을 통해 구현합니다

문법

class 클래스이름 implements 인터페이스이름 { ... }

만약 모든 추상 메소드를 구현하지 않는다면, abstract 키워드를 사용하여 추상 클래스로 선언해야 합니다

7/25 상속연습문제 - 최자영

//주제 : 컴퓨터
// 컴퓨터 - 노트북과 데스크탑 - 노트북 특징
//주중에 더 보강해보기

class Computer {
	
	String price = "비싸다";
	
	void electric(){
		System.out.println("전기가 필요하다.");
		System.out.println(price);
	
	}
}


class Laptop extends Computer {
	
	int weight;
	String brand; 
	
	Laptop() {
		weight = 1;
		brand = "LG"; 
	}

	Laptop(int weight, String brand){
		this.weight = weight;
		this.brand = brand;
	}


	void LaptopInfo() {
		System.out.printf("무게는 %dKG이고 브랜드는 %s 입니다.",weight,brand);
		System.out.println("가벼워요");
		
	}

}




public class Ex0725 {
	public static void main(String[] args) {
		Laptop laptop = new Laptop();
		laptop.LaptopInfo();
		Laptop laptop2 = new Laptop(2, "삼성");
		laptop2.LaptopInfo();
		

	}

}

메뉴

package kr.or.tashow;

import java.util.Scanner;

public class Menu {
	Scanner input = new Scanner(System.in);
	User user;
	Admin admin;
	IO io;
	BikeService bikeService;
	UserSystem userSystem;
	AdminSystem adminSystem;

	public Menu() {
		user = new User();
		admin = new Admin();
		io = new IO();
		bikeService = new BikeService();
		userSystem = new UserSystem();
		adminSystem = new AdminSystem();
		io.initialize();
	}

	public void displayDefaultMenu() {
		// 회원가입, 사용자 인증, 관리자 인증, 프로그램 종료
		while (true) {
			System.out.println("원하는 메뉴의 번호를 입력하세요");
			System.out.println("1. 회원가입");
			System.out.println("2. 사용자인증");
			System.out.println("3. 관리자인증");
			System.out.println("4. 프로그램종료");
			int menu = Integer.parseInt(input.nextLine());

			switch (menu) {
			case 1:
				userSystem.singUp();
				break;
			case 2:
				userSystem.userLogin();
				displayUserMenu();
				break;
			case 3:
				displayAdminMenu();
				break;
			case 4:
				return;
			default:
				System.out.println("잘못입력");
				continue;
			}

		}
	}

	void displayAdminMenu() {
		// 매출관리, 회원목록조회, 자전거관리, 프로그램 종료
		while (true) {
			System.out.println("원하는 메뉴의 번호를 입력하세요");
			System.out.println("1. 매출조회");
			System.out.println("2. 회원목록조회");
			System.out.println("3. 자전거관리");
			System.out.println("4. 이전메뉴");

			int menu = Integer.parseInt(input.nextLine());

			switch (menu) {
			case 1:
				bikeService.calculateTotalSales();
				break;
			case 2:
				io.readUserList();
				break;
			case 3:
				displayBikeMenu();
				break;
			case 4:
				return;
			default:
				System.out.println("잘못입력");
				continue;
			}
		}
	}

	void displayUserMenu() {
		// 대여하기 (> 자전거 목록조회), 반납하기 (> 결제 및 반납), 프로그램 종료

		while (true) {
			System.out.println("원하는 메뉴의 번호를 입력하세요");
			System.out.println("1. 대여하기 (1인용)");
			System.out.println("2. 대여하기 (2인용)");
			System.out.println("3. 결제 및 반납하기");
			System.out.println("4. 이전메뉴");

			int menu = Integer.parseInt(input.nextLine());

			switch (menu) {
			case 1:
				bikeService.rentalBike("S");
				break;
			case 2:
				bikeService.rentalBike("T");
				break;
			case 3:
				System.out.println("반납할 자전거의 일련번호를 입력해주세요");
				String id = input.nextLine();
				bikeService.returnBike(id);
				break;
			case 4:
				return;
			default:
				System.out.println("잘못입력");
				continue;
			}
		}
	}

	void displayBikeMenu() {

		while (true) {
			System.out.println("원하는 메뉴의 번호를 입력하세요");
			System.out.println("1. 자전거등록");
			System.out.println("2. 자전거삭제");
			System.out.println("3. 자전거목록조회");
			System.out.println("4. 자전거대여내역조회");
			System.out.println("5. 이전메뉴");

			int menu = Integer.parseInt(input.nextLine());

			switch (menu) {
			case 1:
				adminSystem.addBike();
				io.writeBikeList();
				break;
			case 2:
				adminSystem.removeBike();
				break;
			case 3:
				io.readBikeList();
				break;
			case 4:
				io.readRentList();
				break;
			case 5:
				return;
			default:
				System.out.println("잘못입력");
				continue;
			}
		}
	}
}

Branch와 Merge

Branch & Merge

branch란

개발을 하다 보면 코드를 여러 개로 복사해야 하는 일이 자주 생긴다. 코드를 통째로 복사하고 나서 원래 코드와는 상관없이 독립적으로 개발을 진행 할 수 있는데 이것을 브랜치라고 한다.
git의 branch가 특별한 이유는 Git의 브랜치는 매우 가볍다. 순식간에 브랜치를 새로 만들고 브랜치 사이를 이동할 수 있다. 다른 버전 관리 시스템과는 달리 Git은 브랜치를 만들어 작업하고 나중에 Merge 하는 방법을 권장한다.

커밋과 이전커밋

Git의 브랜치는 커밋 사이를 가볍게 이동할 수 있는 어떤 포인터 같은 것이다. 기본적으로 Git은 master 브랜치를 만든다. 처음 커밋하면 이 master 브랜치가 생성된 커밋을 가리킨다. 이후 커밋을 만들면 master 브랜치는 자동으로 가장 마지막 커밋을 가리킨다.

새 브랜치 생성

git branch testing

새로 만든 브랜치도 지금 작업하고 있던 마지막 커밋을 가리킨다.

현재 작업 중인 브랜치를 가리키는 HEAD

$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project

-> git log 명령에 --decorate 옵션을 사용하면 확인 가능
->master ''와 testing 이라는 브랜치가 f30ab 커밋 옆에 위치하여 이런식으로 브랜치가 가리키는 커밋을 확인할 수 있음

브랜치 이동

$ git checkout testing

-> HEAD 는 testing 브랜치를 가리킴.

갈라지는 브랜치

현재 브랜치가 가리키고 있는 히스토리가 무엇이고 어떻게 갈라져 나왔는지
-> git log --oneline --decorate --graph --all 이라고 실행하면 히스토리를 출력

$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project

Merge

Merge란

머지는 각 분기된 커밋을 하나의 커밋으로 다시 합치고 싶을 때 사용하는 명령어

Merge
Merge2

은행 시스템

class Bank {
    private ArrayList<Account> accounts;
    private int totalAccount;
    Account account;
    Bank() {
        this.accounts = new ArrayList<Account>();
        this.totalAccount = 0;
    }
    public void addAccount(String accountNo, String name) { // 계좌 생성
        accounts.add(new Account(accountNo, name));
        System.out.println("*** 계좌가 생성 되었습니다 ***");
        System.out.println("[계좌번호: " + accountNo + ", 이름: " + name + "]");
        totalAccount++;
    }
    public ArrayList<Account> findAccounts(String name) {
        System.out.printf("*** [%s]님의 계좌 목록 ***\n", name);
        for (int i = 0 ; i < accounts.size() ; i++) {
            if (name.equals(accounts.get(i).getName())) {
                System.out.println("[" + accounts.get(i)+ "]");
            } else {
                break;
            }
        } return accounts;
    }
    public Account getAccount(String accountNo) {
        Account a = account;
        System.out.printf("*** 계좌번호 [%s]의 조회 결과 ***\n",accountNo);
        for (int i = 0 ; i < accounts.size() ; i++) {
            if (accountNo.equals(accounts.get(i).getAccountNo())) {
                System.out.println("[" + accounts.get(i).toString() + "]");
                a = accounts.get(i);
            } else {
                break;
            }
        }
        return a;
    }
    public ArrayList<Account> getAccounts() {
        System.out.println("*** 전체 계좌 목록 ***");
        for(Account a : accounts) {
            System.out.println(a);
        }
        return accounts;
    }
    public int getTotalAccount() {
        System.out.println("-------------------------");
        System.out.println("전체 개설 계좌 수: " + totalAccount);
        System.out.println("-------------------------");
        return totalAccount;
    }
    @Override
    public String toString() {
        return "" + accounts;
    }
}




class Account {
    private String accountNo;
    private String name;
    private long balance;
    private ArrayList<Transaction> transactions;
    private Bank bank;
    // 생성자
    Account(String accountNo, String name) {
        this.accountNo = accountNo;
        this.name = name;
        this.balance = 0;
        transactions = new ArrayList<Transaction>();
    }
    // 입금한다.
    public long deposit(long amount) {
        this.balance += amount;
        System.out.println(this.name+" 님의 " + this.accountNo + "계좌에 "+amount+"원을 입금합니다. (잔액: "+balance+")");
        transactions.add(new Transaction("입금",amount,balance));
        return balance;
    }
    // 출금한다.
    public long withdraw(long amount) {
        if(balance>=amount) {
            this.balance -= amount;
            System.out.println(this.name+" 님의 " + this.accountNo + "계좌에서 "+amount+"원을 출금합니다. (잔액: "+balance+")");
            transactions.add(new Transaction("출금",amount,balance));
        }else {
            System.out.println("잔액이 부족합니다...");
        }
        return balance;
    }
    // 잔고를 확인한다.
    public long getBalance() {
        System.out.println(this.name+" 님의 "+this.accountNo+" 계좌 잔고를 확인합니다.");
        return balance;
    }
    // 거래내역을 본다.
    public ArrayList<Transaction> getTransactions() {
        System.out.println(this.name+" 님의 "+this.accountNo+" 계좌 거래 내역을 확인합니다.");
        for (Transaction t : transactions) {
            System.out.println(t);
        };
        return transactions;
    }
    public String getAccountNo() {
        return accountNo;
    }
    public String getName() {
        return name;
    }
    @Override
    public String toString() {
        return "계좌번호: " + accountNo +
                " 소유자명: " + name  +
                " 잔액: " + balance;
    }
}



class Transaction{
    private static String transactionDate = getTransactionDate(Calendar.getInstance());
    private static String transactionTime = getTransactionTime(Calendar.getInstance());;
    private String kind;
    private long amount;
    private long balance;

    public Transaction() {
        this.kind=""; // 입금출금
        this.amount = 0;// 거래금액
        this.balance = 0; //잔고
    }
    public Transaction(String kind, long amount, long balance) {

        this.kind = kind; // 입금출금
        this.amount = amount;// 거래금액
        this.balance = balance; //잔고
    }
    @Override
    public String toString() {
        return
                "거래내역 [" + "거래시간: '" + transactionTime + '\'' +
                        ", 거래일자: '" + transactionDate + '\'' +
                        ", 종류: '" + kind + '\'' +
                        ", 금액: " + amount + '\'' +
                        ", 잔액: " + balance +"] \n";
    }
    public static String getTransactionDate(Calendar date) {
        String month = ((date.get((Calendar.MONTH)+1)) < 10) ? "0" + (date.get(Calendar.MONTH)+1) : String.valueOf(date.get(Calendar.MONTH)+1);

        String day = (date.get(Calendar.DATE) < 10) ? "0" + (date.get(Calendar.DATE)) : String.valueOf(date.get(Calendar.DATE));
        return date.get(Calendar.YEAR)+ "년"+
                month + "월" +
                day + "일";
    }
    public static String getTransactionTime(Calendar date) {
        String minute = (date.get(Calendar.MINUTE) < 10) ? "0" + (date.get(Calendar.MINUTE)) : String.valueOf(date.get(Calendar.MINUTE));
        String hour = (date.get(Calendar.HOUR) < 10) ? "0" + (date.get(Calendar.HOUR)) : String.valueOf(date.get(Calendar.HOUR));
        String amPm = (date.get(Calendar.AM_PM)) ==1 ? " 오후" : " 오전";
        String second = (date.get(Calendar.SECOND) < 10) ? "0" + (date.get(Calendar.SECOND)) : String.valueOf(date.get(Calendar.SECOND));
        return
                hour +"시" +
                        minute +"분" +
                        second +"초" +
                        amPm ;
    }
}
public class UML_Bank {
    public static void main(String[] args) {
        Bank bank = new Bank();
        bank.addAccount("3423435", "홍길동");
        bank.addAccount("332423","서희원");
        bank.addAccount("111111","비트캠프");
        bank.findAccounts("홍길동");
        bank.getAccount("3423435");
        bank.getAccounts();
        bank.getTotalAccount();
        Account hong = bank.getAccount("3423435");
        hong.deposit(3000);
        hong.withdraw(2000);
        hong.getBalance();
        System.out.println(hong);
        ArrayList<Transaction> hongtrans = hong.getTransactions();
    }
}

7/25 상속연습문제 - 양수진

##상속연습

class  electronics{
    void electricity() {
        System.out.println("전기를 연결하다.");
    }
}

class Internet{
    String search = "";

    Internet() { // 생성자
        search = "맛집";
    }

    Internet(String search) { // 입력받은 값으로 나타낼
        this.search = search;
    }

    @Override
    public String toString() {
        return search;
    }
}

class Notebook extends  electronics{
    Internet internet;
    String color;


    Notebook() { // 생성자
        this("red", new Internet("옷"));
    }

    Notebook(String color, Internet internet) {
        this.color = color;
        this.internet = internet;
    }

    void notebookInfo() {
        System.out.println("색상은 : " +color);
        System.out.println("검색은 : " +internet);
    }
}



public class weekgroup0725 {
    public static void main(String[] args) {
        Notebook notebook = new Notebook("빨간색", new Internet("나무종류"));
        notebook.notebookInfo();
    }
}

주제잡기 어려워서 그냥 상속이라는 코드를 짜본다에 의의를 두었어용!

자판기 만들기

import java.util.Scanner;

class Machine  {
    // Display display;
    // Operation operation;
    // Product1 product1;
    int returnButton; // 반환버튼
    int money;

    int inputMoney(int money) {
        this.money = money;
        return money;
    }

}

class Operation extends Machine  {
    Product1[] productList; // 추가
    Receipt receipt;
    int count; // 추가

    Operation () {
        productList = new Product1[] {new Product1("콜라",800), new Product1("커피",500),new Product1("초콜릿",1000),new Product1("과자",700)};
    }
    void display() { // 콜라, 커피, 초콜릿, 과자 메뉴 출력
        for(int i = 0 ; i < productList.length ; i++) {
            System.out.println(productList[i].name + "," + productList[i].price + "원");
        }
    }

    void lightOnOff() { // 잔액이 물품 가격보다 같거나 클경우 물품 선택 버튼에 불이 들어온다.
        inputMoney(money);
        for(int i = 0 ; i < productList.length ; i++) {
            if (money >= productList[i].price) {
                productList[i].productButton = true;
            } else {
                break;
            }
        }
    }

    int chooseProduct(int money) { // 제품을 선택한다.
        Scanner sc = new Scanner(System.in);
        int balance = 0;
            display();
            lightOnOff();
            System.out.println("구매 하실 제품을 선택해 주세요");
            int input = Integer.parseInt(sc.nextLine());
            while (input >= 1 && input <= 4) {
                switch (input) {
                    case 1: // 콜라
                        balance = money - productList[0].price;
                        // receipt.inputReceipt();
                        break;
                    case 2: // 커피
                        balance = money - productList[1].price;
                        // receipt.inputReceipt();
                        break;
                    case 3: // 초콜릿
                        balance = money - productList[2].price;
                        //receipt.inputReceipt();
                        break;
                    case 4: // 과자
                        balance = money - productList[3].price;
                        // receipt.inputReceipt();
                        break;
                }
            }
            System.out.println("잔액: " + balance);
            askReturn();

            return balance;
        }

    void askReturn() {
        Scanner sc = new Scanner(System.in);
        System.out.println("잔돈을 돌려 받으시겠습니까? 예:1, 아니오:아무 버튼");
        int input = Integer.parseInt(sc.nextLine());
        if(input != 1) {
            return;
        } else {
            returnButton = 1;
            returnBalance(money);
            printReceipt();
        }
    }

    void returnBalance(int balance) { // 잔액을 반환한다.
        System.out.println("잔액을 반환합니다");
        System.out.println(balance);
        this.money = 0;
    }

    void printReceipt() { // 영수증이 출력된다. (잔액이 1원 이상이면 사용자가 반환번튼을 누르면 반환 되고 나서 출력, 잔액이 0원이면 자동 출력)
        System.out.println("=========영수증=========");
        for(int i = 0 ; i < count ; i++) {
            System.out.println(receipt.itemList[i].name + "," + receipt.itemList[i].price + "원");
        }
        System.out.println("총 구매금액: " + receipt.totalPrice + "원");
    }
}

// class Display extends Machine { } 함수 옮김
// void displayBalance() { // 잔액을 표시한다. chooseProduct에 들어감}

class Product1 {
    boolean productButton;
    Product1[] productList; // 다이어그램에 있는데 못 씀
    int price;
    String name; // 다이어그램에 없음

    Product1 () {
        Product1[] productList = {new Product1("콜라",800), new Product1("커피",500),new Product1("초콜릿",1000),new Product1("과자",700)};
    }
    Product1 (String name, int price) {
        this.name = name;
        this.price = price;
        this.productButton = false;
        // this.productList = {new Product1("콜라",800), new Product1("커피",500),new Product1("초콜릿",1000),new Product1("과자",700)};
        // 왜 안되는지 여쭤보기!
    }

}

class Receipt extends Operation {
    Product1[] itemList = new Product1[10];
    int totalPrice;

    Receipt () {
        this.totalPrice = 0;
    }

    void inputReceipt () {
        totalPrice = totalPrice + productList[0].price;
        itemList[count++] = productList[0];
    }

}

public class UML_VendingMachine_2 {
    public static void main(String[] args) {
        Operation operation = new Operation();
        operation.chooseProduct(5000);
    }

}

RentList - 유저 핸드폰번호 추가

Class UserSystem - userLogin() 에서 추가

String userLogin () {

        while (true) {
            System.out.println("ID를 입력해주세요");
            userPhoneNum = input.nextLine().trim();

            Matcher phone = userPhonNumPattern.matcher(userPhoneNum);
            if (phone.find() == false) {
                System.out.println("형식오류. 재입력");
                System.out.println("ex) 010-1234-5678 ");

            } else {
                System.out.println("비밀번호를 입력해주세요");
                userPwd = input.nextLine();

            }if (!userList.containsKey(userPhoneNum)) {
                System.out.println("ID가 맞지 않습니다.재입력");
            } else {
                if (userList.get(userPhoneNum).getUserPwd().equals(userPwd)) {
                    System.out.println("인증 완료되었습니다");
                    Menu.cur_user_id = userPhoneNum; //인증완료시 누가 로그인 했는지에 대해 아이디 넣기
                    break;
                } else {
                    System.out.println("비밀번호 오류입니다. 재입력");
                }
            }
        }
        return userPhoneNum;
    }

}

Class Menu - 필드값에서 추가

public class Menu {
    static String cur_user_id = ""; //누가 로그인 했는지 추가(누구의ID)
    Scanner input = new Scanner(System.in);
    User user;
    Admin admin;
    IO io;
    BikeService bikeService;
    UserSystem userSystem;
    AdminSystem adminSystem;

class BikeService - rentalBike에서 추가

void rentalBike(String type) { // 대여
        if (bikeList.isEmpty()) {
            System.out.println("대여 가능한 자전거가 없습니다");
        } else {
            System.out.println("값 =" +Menu.cur_user_id);
            for (String key : bikeList.keySet()) {
                if (key.startsWith(type) && bikeList.get(key).getRentalStatus().equals(RentalStatus.AVAILABLE)) {
                    Bike bike = bikeList.get(key);
                    bike.setRentalStatus(RentalStatus.UNAVAILABLE);
                    System.out.println("대여된 자전거: " + key + bike.getRentalStatus());
                    //rent객체의 유저 ID 필드값 추가
                    rentList.add(new RentList(key, time.setStartTime() ,Menu.cur_user_id));
                    System.out.println(rentList.get(0).getUserPhoneNum());
                    io.writeBikeList();
                    io.writeRentList();
                    break;
                }
            }
        }
    }

class RentList - 생성자에서 추가

public class RentList implements Serializable {
    private String id;
    private String userPhoneNum;
    private Calendar startTime;
    private Calendar endTime;
    private int fee;

    RentList () {
        this("" ,null , null);
        this.fee = 0;
    }

    //생성자에 userPhoneNum추가
    RentList(String id,Calendar startTime ,String userPhoneNum) {
        this.id = id;
        this.startTime = startTime;
        this.userPhoneNum = userPhoneNum;
    }

class Time

package kr.or.tashow;

import java.text.SimpleDateFormat;
import java.util.Calendar;

public class Time {
    Calendar startTime;
    Calendar endTime;
    SimpleDateFormat dateFormat;
    int diffHour;
    int diffMinute;

    public Time() {
        dateFormat = new SimpleDateFormat("HH:mm");
    }

    public Calendar inputStartTime (){ // 시작시각 입력
        startTime = Calendar.getInstance();
        System.out.println(dateFormat.format(startTime.getTime()));
        return startTime;
    }
    public Calendar inputEndTime (){ // 종료시각 입력
        endTime = Calendar.getInstance();
        System.out.println(dateFormat.format(endTime.getTime()));
        return endTime;
    }

    public int getTime(Calendar startTime, Calendar endTime) { // 시간 차이
        diffHour = endTime.get(Calendar.HOUR_OF_DAY) - startTime.get(Calendar.HOUR_OF_DAY);
        diffMinute = endTime.get(Calendar.MINUTE) - startTime.get(Calendar.MINUTE);
        if (diffMinute > 0) {
            return diffHour++;
        } else {
            return diffHour;
        }
    }
}

일단 초안

class BikeService(자전거 클래스의 데이터 저장소)

  • 우선은 완성이 목표이기에 일련번호는 S0001형태가 아니라 그냥 1, 2, 3, 4, 5, 6...으로 하고 나중에 추가 수정해야할 사항
public class BikeService {

    ArrayList<Bike> bikeList;

    public BikeService() { // Single 10개 Twin 10개 만듬 ,,
        this.bikeList = new ArrayList<Bike>();
        for(int i = 0; i < 20; i++) {
            this.bikeList.add(new Bike("i", i > 9 ? BikeType.Twin: BikeType.Single, RentalStatus.AVAILABLE, i > 9 ? 1000 : 2000));
        }
    }


    public Bike rentalBike(BikeType type) { // 대여
        for(Bike bike: bikeList) { // bikeList
            if (bike.getType() == type && bike.getRentalStatus() == RentalStatus.AVAILABLE) {
                bike.setRentalStatus(RentalStatus.UNAVAILABLE);
                return bike;
            }
        }
        return null;
    }

    public Bike returnBike(String id) { // 반납

        for(Bike bike: bikeList) { // bikeList
            if (bike.getId().equals(id)) { // 리스트에 아이디값과 인자로 받은 아이디값과 같으면 
                bike.setRentalStatus(RentalStatus.AVAILABLE); // 대여가능으로 바꿔주고 
                return bike; // 바이크에 리턴해준다.
            }
        }
        return null;

    }

}

AdminSystem Class - 관리자 인증

public class AdminSystem {
    Bike bike;
    String id;
    String pw;
    BikeService bikeService;
    int countSingle;
    int countTwin;
    HashMap<String, String> adminMap = new HashMap<String, String>();


    public AdminSystem() {
        bike = new Bike();
        bikeService = new BikeService();
        this.countSingle = 0;
        this.countTwin = 0;
        this.id = "";
        this.pw = "";
        adminMap.put("admin", "admin!");
    }


    public void adminLogin() {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("관리자 ID를 입력해주세요");
            String id = sc.nextLine().trim().toLowerCase();

            System.out.println("관리자 비밀번호를 입력해주세요");
            String pwd = sc.nextLine().trim();

            if(!adminMap.containsKey(id)) {
                System.out.println("id가 맞지 않습니다. 재입력 해주세요.");
            }else {
                if(adminMap.get(id).equals(pwd)) {
                    System.out.println("관리자 인증이 완료되었습니다.");
                    break;
                }else {
                    System.out.println("비밀번호가 맞지 않습니다. 재입력 해주세요");
                }
            }

        }

    }

class IO - 회원목록/자전거목록 리스트 내부 데이터 정렬

package kr.or.tashow;

import java.io.*;
import java.util.*;

import static kr.or.tashow.BikeService.bikeList;
import static kr.or.tashow.BikeService.rentList;

public class IO {
	private String fileRoot;

	public IO() {
		fileRoot = "C:\\Bit\\Java\\Labs_J\\";
	}

	void startSystem() {
		File file = new File(fileRoot + "userlist.txt");
		File file2 = new File(fileRoot + "rentlist.txt");
		File file3 = new File(fileRoot + "bikelist.txt");

		if (!file.exists()) {
			writeUserList();
		}
		if (!file2.exists()) {
			writeRentList();
		}
		if (!file3.exists()) {
			writeBikeList();
		}

		FileInputStream fis = null;
		BufferedInputStream bis = null;
		ObjectInputStream ois = null;

		try {
			fis = new FileInputStream(file);
			bis = new BufferedInputStream(fis);
			ois = new ObjectInputStream(bis);

			UserSystem.userList = (HashMap<String, User>) ois.readObject();

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				ois.close();
				bis.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		try {
			fis = new FileInputStream(file2);
			bis = new BufferedInputStream(fis);
			ois = new ObjectInputStream(bis);

			rentList = (ArrayList<RentList>) ois.readObject();

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				ois.close();
				bis.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		try {
			fis = new FileInputStream(file3);
			bis = new BufferedInputStream(fis);
			ois = new ObjectInputStream(bis);

			bikeList = (HashMap<String, Bike>) ois.readObject();

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				ois.close();
				bis.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void writeUserList() {// Filewrite > UserList
		File userList = new File(fileRoot + "userlist.txt");
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		ObjectOutputStream oos = null;

		try {
			fos = new FileOutputStream(userList);
			bos = new BufferedOutputStream(fos);
			oos = new ObjectOutputStream(bos);

			oos.writeObject(UserSystem.userList);

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				oos.close();
				bos.close();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void readUserList() {
		File file = new File(fileRoot + "userlist.txt");
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		ObjectInputStream ois = null;

		try {
			fis = new FileInputStream(file);
			bis = new BufferedInputStream(fis);
			ois = new ObjectInputStream(bis);

			UserSystem.userList = (HashMap<String, User>) ois.readObject();
			TreeMap<String, User> userListSort = new TreeMap<String, User>(UserSystem.userList);
			Set<String> keyset = UserSystem.userList.keySet();
			Iterator<String> keyiterator = userListSort.keySet().iterator();

			System.out.println("======== 비트를 타쇼 회원 리스트 =========");

			String userListKey;
			User userListValue;

			while (keyiterator.hasNext()) {
				userListKey = (String) keyiterator.next();
				userListValue = (User) userListSort.get(userListKey);
				System.out.println(userListValue);
			}

			System.out.println("==========================================");

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				ois.close();
				bis.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void writeBikeList() {
		File file = new File(fileRoot + "bikelist.txt");
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		ObjectOutputStream oos = null;

		try {
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			oos = new ObjectOutputStream(bos);

			oos.writeObject(bikeList);

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				oos.close();
				bos.close();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void readBikeList() {
		File file = new File(fileRoot + "bikelist.txt");
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		ObjectInputStream ois = null;

		try {
			fis = new FileInputStream(file);
			bis = new BufferedInputStream(fis);
			ois = new ObjectInputStream(bis);

			bikeList = (HashMap<String, Bike>) ois.readObject();
			TreeMap<String, Bike> bikeListSort = new TreeMap<String, Bike>(bikeList);
			Set<String> keyset = bikeList.keySet();
			Iterator<String> keyiterator = bikeListSort.keySet().iterator();

			System.out.println("===== 비트를 타쇼 자전거 등록 리스트 =====");

			String bikeListKey;
			Bike bikeListValue;

			while (keyiterator.hasNext()) {
				bikeListKey = (String) keyiterator.next();
				bikeListValue = (Bike) bikeListSort.get(bikeListKey);
				System.out.println("[" + bikeListKey + "]" + bikeListValue);
			}

			System.out.println("==========================================");

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				ois.close();
				bis.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void writeRentList() {
		File file = new File(fileRoot + "rentlist.txt");
		FileOutputStream fos = null;
		BufferedOutputStream bos = null;
		ObjectOutputStream out = null;

		try {
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			out = new ObjectOutputStream(bos);
			out.writeObject(rentList);

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				out.close();
				bos.close();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void readRentList() {
		File file = new File(fileRoot + "rentlist.txt");
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		ObjectInputStream ois = null;

		try {
			fis = new FileInputStream(file);
			bis = new BufferedInputStream(fis);
			ois = new ObjectInputStream(bis);

			rentList = (ArrayList<RentList>) ois.readObject();

			for (RentList rent : rentList) {
				System.out.println(rent);
			}

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				ois.close();
				bis.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void loadRentList() {

		File file = new File(fileRoot + "rentlist.txt");
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		ObjectInputStream ois = null;

		try {
			fis = new FileInputStream(file);
			bis = new BufferedInputStream(fis);
			ois = new ObjectInputStream(bis);

			rentList = (ArrayList<RentList>) ois.readObject();

		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				ois.close();
				bis.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	void deleteBikeList() {
		// 파일의 경로 + 파일명
		File file = new File(fileRoot + "bikelist.txt");
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		ObjectInputStream ois = null;

		File deleteFile = new File(fileRoot + "bikelist.txt");

		// 파일이 존재하는지 체크 존재할경우 true, 존재하지않을경우 false
		if (deleteFile.exists()) {

			// 파일을 삭제합니다.
			deleteFile.delete();

			System.out.println("자전거 리스트를 삭제하였습니다");

		} else {
			System.out.println("파일이 존재하지 않습니다");
		}
		writeBikeList();
	}
}

class user - 회원가입

package kr.or.tashow;

import java.awt.Menu;
import java.io.File;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// 내가 해야하는 것
// 1. 정규표현식에 맞는 전화번호, 비밀번호 받기 
// 2. 전화번호가 중복인 경우, 회원 가입 실패 하기
// 3. 입력한 값은 wirteUserInfo 라는 파일에 저장되게 하기 // 해시맵? 

class SignUp {
    String userName; // 이름
    String userPhoneNum; // 전화번호
    String userPwd; // 비밀번호
    Scanner scn = new Scanner(System.in); // 입력받기
    File userInfoFile = new File("C://userInfoFile/"); // 파일 생성되는 곳 
   
   void User() {
        this.userName = userName;
        this.userPhoneNum = userPhoneNum;
        this.userPwd = userPwd;
      
    }

    void insertUserInfo() { // 가입 정보 입력
    	Pattern userNamePattern = Pattern.compile("^[가-힣]*$");// 이름 한글만
    	Pattern userPhonNumPattenrn = Pattern.compile("^010-\\d{4}-\\d{4}$");// 전화번호 형식
    	Pattern userPwdPattenrn =Pattern.compile("^[a-zA-Z0-9]{6,8}$"); // 비밀번호 형식
    
    	while (true) {
   			System.out.print("이름 : ");
    		this.userName = scn.nextLine();
    		Matcher ch = userNamePattern.matcher(this.userName);
    			if (ch.find() != true) {
    				System.out.println("올바르지 못한 형식입니다. ");
    				continue;
    			} 
    			
    			
    		System.out.print("전화번호(ID) : ");
   			this.userPhoneNum = scn.nextLine();
    		Matcher ch2 = userPhonNumPattenrn.matcher(this.userPhoneNum);
    			if (ch2.find() != true) {
    				System.out.println("전화번호는 010-0000-0000 형식으로 입력해주세요.");
    			} 
//    		else if(????모르겠어 ㅠㅠ) { // 전화번호가 중복인 경우 로그인창으로 가기 
//    			System.out.println("이미 가입완료된 아이디입니다.");
//    		}
    			
    			
    		System.out.println("비밀번호는 영문,숫자로만 입력가능합니다.");
    		System.out.println("최소 6자 ~ 최대 8자로만 가능합니다.");
    		System.out.print("비밀번호 : ");
    		this.userPwd = scn.nextLine();
    		Matcher ch3 = userPwdPattenrn.matcher(this.userPwd);
    			if (ch3.find() == false) {
    				System.out.println("올바르지 못한 형식입니다. ");
    			}
   
    		System.out.println("회원가입이 완료되었습니다.");
    		return;
//    		Menu.displayDefaultMenu();
    	}
    		
    	
//   		if(ch3.find()== false) {
//   		}
    }

    		


	void checkFormat() { // 형식 확인
		// 필요가 없는 거 같은데 
	}

    void writeUserInfo() { //회원 목록 파일 저장
//    	File writeUserInfo = new File("C://UserInfo/wirteUserInfo.txt"); // 파일 저장 경로
    	
    }



public static void main(String[] args) {
	SignUp signup = new SignUp();
	signup.insertUserInfo();

}
}
'''

Cinema

/*
잘 안보이면 여기 >> https://colorscripter.com/s/sImbsOv
조회/취소 메뉴에서 0 입력시 초기 메뉴로, 예약번호가 아닌 값 입력시 입력오류라고 뜨게 만듦

            	if (inputReserveNum.equals("0")) {      입력값이 0이면 초기메뉴로...
            		break loop3;
            	}else { 여기에 for문 

                         ...
                         ...

                                default:
                                    System.out.println("예매번호 입력 오류");     예매번호가 유효하지 않으면 오류 띄우기

*/

import java.util.Random;
import java.util.Scanner;
class Cinema {
    Scanner sc = new Scanner(System.in);
    Random r = new Random();
    public String[][] seat = new String[3][5]; // 3행 5열짜리 좌석
    public String[][] reserveNumArr = new String[3][5]; // 예약번호를 저장할 배열
    int i, j;
    String ran;
    // 좌석에 A0 A1 ... C3 C4 까지의 값을 넣어줌 (빈 좌석)
    private String[][] createSeat () {
        char row = 'A';
        for (i = 0; i < seat.length; i++) {
            for (j = 0; j < seat[i].length; j++) {
                seat[i][j] = Character.toString((char) (row + i)) + j;
            }
        }
        return seat;
    }
    // 메뉴 출력
    private int displayMenu() {
        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("************************");
        int menu = 0;
        do { // 메뉴 번호 오류 확인
            try {
                menu = Integer.parseInt(sc.nextLine());
                if (menu >= 1 && menu <= 4) {
                    break;
                } else {
                    throw new Exception("메뉴 번호 오류");
                }
            } catch (Exception e) {
                System.out.println("오류 발생: " + e.getMessage());
                System.out.println("메뉴 1~4번 중 다시 입력해 주세요");
            }
        } while (true);
        return menu;
    }
    // 메뉴 실행 매소드
    public void menuReserve() {
        createSeat(); // 메뉴가 실행되면 가장 먼저 좌석에 초기값을 할당해준다
        loop:
        while (true) {
            switch (displayMenu()) {
                case 1:
                    cinemaReserve();
                    break;
                case 2:
                    checkReserve();
                    break;
                case 3:
                    cancelReserve();
                    break;
                case 4:
                    System.out.println("프로그램을 종료합니다");
                    break loop;
                default:
                    System.out.println("번호를 잘못 입력 했습니다");
                    return;
            }
        }
    }
    // 좌석의 예약 현황을 출력
    private void showReserve () {
        System.out.println("*********좌석 현황*********");
        for (String[] seatArr : seat) {
            for (String col : seatArr) {
                System.out.printf("[%s]", col);
            }
            System.out.println();
        }
        System.out.println("-------------------------");
    }
    // 메뉴 1번: 좌석 예약
    private String[][] cinemaReserve () {
    loop: do { try {
        showReserve(); // 먼저 예약 현황을 출력
        System.out.println("좌석을 선택해 주세요 예) A1");
        System.out.println("이미 예매된 좌석은 [XX]으로 표시됩니다");
            String seatNum = sc.nextLine(); // 예매하고자 하는 좌석 번호를 입력 받는다
            char seatNumRow = (char) (seatNum.charAt(0)); // 좌석 번호의 첫 번째 글자(알파벳)를 char로 형변환 (행)
            int colCount = (int) (seatNum.charAt(1)-'0');
            // 좌석 번호의 두 번째 글자(숫자)를 아스키코드 '0'을 빼주고, int로 형변환 (열)
            int rowCount = 0; // 열 값은 알파벳이므로 숫자로 변환해주어야 함 > 숫자로 된 열 값의 초기화
                switch (seatNumRow) { // 알파벳으로 입력된 열 값을 숫자로 변환하여 저장해준다
                    case 'A':
                        rowCount = 0;
                        break;
                    case 'B':
                        rowCount = 1;
                        break;
                    case 'C':
                        rowCount = 2;
                        break;
                    default:
                        rowCount = 4;
                        break;
                }
                    loop3 : if (rowCount == 4 || colCount >= 5) { // 좌석 번호를 잘못 입력 했을 경우, 오류 문구 출력
                        System.out.println("입력값 오류");
                        System.out.println("올바른 좌석값을 입력해 주세요");
                        break loop3;
                    } else if (seat[rowCount][colCount].equals("XX")) { // 이미 예약된 좌석일 경우 다시 입력 하라는 문구 출력
                        System.out.printf("선택하신 좌석은 [%s]입니다 \n", seatNum);
                        System.out.println("해당 좌석은 이미 예약된 좌석 입니다");
                        System.out.println("좌석을 다시 선택해 주세요");
                    } else { // 둘 다 아닐 경우, 예매 가능한 좌석 안내 문구 출력
                        System.out.printf("선택하신 좌석은 [%s]입니다 \n", seatNum);
                        System.out.println("예매 가능합니다. 예약하시겠습니까?");
                        System.out.println("예(1), 좌석 재선택(2), 초기 화면(3)을 입력해 주세요");
                        int input = Integer.parseInt(sc.nextLine()); // 예매할것인지 여부 입력값 받음
                        switch (input) {
                            case 1: // '예'를 선택했을 경우
                                seat[rowCount][colCount] = "XX"; // 해당 좌석에는 예매됨 값을 할당
                                ran = Integer.toString(r.nextInt(8) + 1); // 8자리 예매번호 생성
                                for (int i = 0; i < 7; i++) {
                                    ran += Integer.toString(r.nextInt(9));
                                }
                                reserveNumArr[rowCount][colCount] = ran; // 예매번호 배열에 생성된 번호 저장
                                System.out.println("예약이 완료되었습니다");
                                System.out.printf("예매한 좌석 번호: [%s] / 예매번호: [%s] \n", seatNum, ran);
                                break loop;
                            case 2:
                                break; // 좌석 선택으로 다시 돌아감
                            case 3:
                                break loop;// 메뉴 화면으로 돌아감
                            default:
                                throw new Exception("메뉴 선택 오류");
                        }
                    }
    } catch (Exception e) {
        System.out.println("입력하신 정보를 찾을 수 없습니다");
        System.out.println("메뉴로 돌아갑니다");
        break;
    }
        } while (true);
    return seat;
        }
        // 예매 내역 확인
        private void checkReserve() {
        loop2: do {
            System.out.println("예매번호를 입력해 주세요.\n전단계로 돌아가시려면 0을 입력해주세요.");
            try {
                String inputReserveNum = sc.nextLine(); // 사전에 받은 예매번호 값 입력 받음
                if (inputReserveNum.equals("0")) {
            		break loop2;
            	}else {
                for (i = 0; i < reserveNumArr.length; i++) {
                    for (j = 0; j < reserveNumArr[i].length; j++) {
                        if (inputReserveNum.equals(reserveNumArr[i][j])) { // 다시 입력 받은 값이 맞는지 확인
                            int rowCount = i;
                            char rowCountChar = 'A';
                            int colCount = j;
                            switch (rowCount) {
                                case 0:
                                    rowCountChar = 'A';
                                    break;
                                case 1:
                                    rowCountChar = 'B';
                                    break;
                                case 2:
                                    rowCountChar = 'C';
                                    break;   
                            }
                            System.out.printf("고객님이 예매하신 좌석은 [%c%d]입니다 \n", rowCountChar, colCount);
                            break loop2;
                        }
                    }
                }
            }
            throw new Exception("예매번호 입력 오류"); // 입력된 내용이 일치하지 않을 시, 오류 문구 출력
            } catch (Exception e) {
                System.out.println("오류 내용: " + e.getMessage());
                System.out.println("잘못된 값입니다. 다시 입력해 주세요.");
            }
        } while (true);
        }
        // 예매 취소
        public void cancelReserve() {
        loop3: do {
                System.out.println("예매번호를 입력해 주세요.\n전단계로 돌아가시려면 0을 입력해주세요."); // 확인 메소드와 동일하게 예매번호를 입력받음
                try {
                	String inputReserveNum = sc.nextLine();
                	if (inputReserveNum.equals("0")) {
                		break loop3;
                	}else {
                    for (i = 0; i < reserveNumArr.length; i++) {
                        for (j = 0; j < reserveNumArr[i].length; j++) {
                            if (inputReserveNum.equals(reserveNumArr[i][j])) {
                                int rowCount = i;
                                int colCount = j;
                                char rowCountChar = 'A';
                                switch (rowCount) {
                                    case 0:
                                        rowCountChar = 'A';
                                        break;
                                    case 1:
                                        rowCountChar = 'B';
                                        break;
                                    case 2:
                                        rowCountChar = 'C';
                                        break;
                                    default:
                                        System.out.println("예매번호 입력 오류");
                                }
                                System.out.printf("고객님이 예매하신 좌석은 [%c%d]입니다 \n", rowCountChar, colCount);
                                System.out.println("예매를 취소하시겠습니까?");
                                System.out.println("예(1), 아니오(2)");
                                int cancelOX = Integer.parseInt(sc.nextLine()); // 취소할 것인지 여부 입력 받음
                                String colCountString = Integer.toString(colCount);
                                String rowCountString = Character.toString(rowCountChar);
                                String seatNum = rowCountString + colCountString; // 행열값을 String으로 형변환 후 결합
                                switch (cancelOX) {
                                    case 1:
                                        seat[rowCount][colCount] = seatNum;
                                        // 예매 취소 선택 시, 해당 배열에 위에서 결합한 행열값을 넣어줌
                                        reserveNumArr[rowCount][colCount] = "";
                                        // 예매번호를 null 값으로 초기화
                                        System.out.println("예매가 취소되었습니다");
                                        break loop3;
                                    case 2:
                                        break loop3;
                                    default:
                                        System.out.println("올바른 번호를 입력해 주세요");
                                }
                            }
                        }
                    }
                }
                } catch (Exception e) {
                    System.out.println("오류 내용: " + e.getMessage());
                    System.out.println("잘못된 값입니다. 다시 입력해 주세요.");
                    break;
                }
            } while (true);
        }
}

public class Cinema0724 {
    public static void main(String[] args) {
        Cinema ci = new Cinema();
        ci.menuReserve();
    }
}

class BikeService - 대여한 자전거 없을 경우

void returnBike() 메소드에서 추가

void returnBike() { // 반납
        Scanner input = new Scanner(System.in);  //여기서부터
        RentList my_list = null;

        for (int i = 0 ; i < rentList.size() ; i++) {
            if (rentList.get(i).getUserPhoneNum().equals(Menu.cur_user_id)) { //대여한게 있다면
                my_list = rentList.get(i);
            }
        }

        if (my_list == null) { //RentList에 대여한 목록에 없다면
            System.out.println("대여 중인 자전거가 없습니다");
            return;
        }

        System.out.println("반납할 자전거의 일련번호를 입력해주세요");
        String id = input.nextLine();   //여기까지 추가

        for(String key : bikeList.keySet()) { // bikeList
            io.loadRentList();
            if (bikeList.containsKey(id) && bikeList.get(id).getRentalStatus().equals(RentalStatus.UNAVAILABLE)) {
                for (int i = 0 ; i < rentList.size() ; i++) {
                     if (rentList.get(i).getId().contains(id)) {
                        RentList list = rentList.get(i);
                        // time.inputEndTime(i); > 진짜 시간
                        time.testEndTime(i); // > 테스트용 시간
                        int fee = calculateFee(id,list.getStartTime(),list.getEndTime()); // 시간입력
                        payFee(i,fee,id); // 계산
                        io.writeBikeList();
                        io.writeRentList();
                        break;
                    }
                }
                break;
            } else {
                System.out.println("일련번호가 일치하지 않습니다.");
                break;
            }
        }
    }

void payFee() 메소드에서 자전거 반납 후 rentlist에서 삭제 기능 추가

void payFee(int index, int fee, String id) {
        DecimalFormat df = new DecimalFormat("#,###");
        System.out.println("결제요금: " + df.format(fee) + "원");
        System.out.println("[요금안내] 1시간 당 1인용 : 1,000원, 2인용 : 2,000원");
        System.out.println("* 요금은 시간 단위로 계산되어 1분 초과 시부터 올림 적용됩니다");
        System.out.println("결제하시겠습니까?");
        System.out.println("1. 예 | 2. 아니오 (취소)");
        Scanner scan = new Scanner(System.in);
        int input = Integer.parseInt(scan.nextLine());
        if (input == 1) {
            rentList.get(index).setFee(fee);
            bikeList.get(id).setRentalStatus(RentalStatus.AVAILABLE); 
            rentList.remove(index); //자전거 반납 후 렌트 리스트에서 삭제
           io.writeRentList();
            io.writeBikeList();
            System.out.println("결제가 완료되었습니다.");
            System.out.println("이용해 주셔서 감사합니다 :D");

class Menu - void displayUserMenu() 메소드 수정

while (true);

                switch (menu) {
                    case 1:
                        bikeService.rentalBike("S");
                        break;
                    case 2:
                        bikeService.rentalBike("T");
                        break;
                    case 3:
                        bikeService.returnBike();  // 여기 수정
                        break;
                    case 4:
                        return;
                }
            }
    }

7/25 상속연습문제 - 남궁은

캡슐 커피 내리다가 짜봤습니당

class CapsuleCoffeeMachine {
	
	Power power;
	String color;
	
	void PowerOn() {
		System.out.println("동작하겠습니다");
	}
	
	void PowerOff() {
		System.out.println("종료하겠습니다");
	}
	
	void Brewing() {
		System.out.println("추출을 시작하겠습니다");
		}
	
	void CapsuleRelease() {
		System.out.println("캡슐을 배출하겠습니다");
	}
	
	void MachineCleaning() {
		System.out.println("청소를 시작하겠습니다");
		}
	
	CapsuleCoffeeMachine(Power power, String color) {
		this.power = power;
		this.color = color;
	}
	
	CapsuleCoffeeMachine() {
		this.power = new Power("Electric");
		this.color = "Matt Black";
	}
}

class Power {
	String type;
	
	Power(String type) {
		this.type = type;
	}
	
	Power() {
		this.type = "Electric";
	}
}

class Nespresso extends CapsuleCoffeeMachine {
	CapsuleType capsuleType;
	CapsuleName capsuleName;
	Virtuo virtuo;
	
	Nespresso() {
		
		this.virtuo = new Virtuo("VirtuoPlus", 1.2, 250000);
		this.capsuleType = new CapsuleType("Espresso", 40);
		this.capsuleName = new CapsuleName("Diavolitto", "강한 로스팅, 진하고 강렬한 풍미, 크리미한 바디감", 650);
		
	}
	
	void nesInfo() {
		
		System.out.printf("기기 이름: %s / 물탱크 용량(L): %.1f / 기기 가격(원): %d \n", virtuo.virtuoPlus, virtuo.waterAmount, virtuo.machinePrice);
		System.out.printf("전원 타입: %s / 색상: %s  \n", power.type, color);
		System.out.printf("캡슐 타입: %s / 추출량(ml): %d \n", capsuleType.type, capsuleType.releaseAmount);
		System.out.printf("캡슐 이름: %s / 맛: %s / 캡슐 1개 가격(원): %d \n", capsuleName.name, capsuleName.taste, capsuleName.price);
		
	}
}

class Virtuo {
	String virtuoPlus;
	double waterAmount;
	int machinePrice;
	
	Virtuo(String virtuoPlus, double waterAmount, int machinePrice) {
		this.virtuoPlus = virtuoPlus;
		this.waterAmount = waterAmount;
		this.machinePrice = machinePrice;
	}
	
	Virtuo() {
		this.virtuoPlus = "VirtuoPlus";
		this.waterAmount = 1.2;
		this.machinePrice = 250000;
	}
}

class CapsuleType {
	String type;
	int releaseAmount;
	
	CapsuleType(String type, int releaseAmount) {
		this.type = type;
		this.releaseAmount = releaseAmount;
	}
	
	CapsuleType() {
		this.type = "Espresso";
		this.releaseAmount = 40;
	}
}

class CapsuleName {
	String name;
	String taste;
	int price;
	
	CapsuleName(String name, String taste, int price) {
		this.name = name;
		this.taste = taste;
		this.price = price;
	}
	
	CapsuleName() {
		this.name = "Diavolitto";
		this.taste = "강한 로스팅, 진하고 강렬한 풍미, 크리미한 바디감";
		this.price = 650;
	}

}

public class Inherit_Coffee {
    public static void main(String[] args) {
    	Nespresso nes = new Nespresso();
    	
    	nes.PowerOn();
    	nes.nesInfo();
    	nes.Brewing();
    	nes.CapsuleRelease();
    	nes.MachineCleaning();
    	nes.PowerOff();
    		
    }
}

Refactoring - 메뉴 로직 간결화

메뉴 로직 간결화

  • 메뉴의 중복되는 3부분을 1개의 메소드로 해결하여 코드 간결화

ViewUtil 클래스를 추가

static int displayMenu(String menusName, String[] menus) {
        Scanner scanner = new Scanner(System.in);
        do {
            System.out.println("******비트를 타쇼 " + menusName + " ******");
            System.out.println("        원하는 메뉴의 번호를 입력하세요");
            for(int i = 0; i < menus.length; i ++) {
                System.out.printf("%d. %s%n", i+1, menus[i]);
            }
            System.out.println("**********************************");
            try {
                int menu = Integer.parseInt(scanner.nextLine());
                if(menu >= 1 && menu <= menus.length) {
                    continue;
                } else {
                    throw new Exception("메뉴 번호 오류");
                }
            } catch (Exception e) {
                System.out.println("오류발생: " + e.getMessage());
                System.out.println("1~4 중 다시 입력해주세요");
            }
        } while (true);
    }

메뉴 method 예시

public void showUserPage() {
        bikeService.addBike(BikeType.Single);

        int menu = ViewUtil.displayMenu("자전거 대여 시스템" , new String[] {
                "대여하기 (1인용)",
                "대여하기 (2인용)",
                "결제 및 반납하기",
                "이전메뉴"
        });
    }

결과

image

7/28 - 양수진

추상클래스 : 인터페이스 (interface)

인터페이스란, 표준, 약소그 규약, 규칙을 만드는 행위

  • 추상클래스와 인터페이스의 공통점

스스로 객체 생성 불가능 ( new 사용불가)

  • 차이점
  1. 추상클래스 ( 완성 + 미완성), 인터페이스는 미완성만,

  2. 추상클래스 : 단일상속(계층적 상속)

    인터페이스 : 다중상속

→ class Test extends Car implements Ia, Ib, Ic

  • 사용

→ 일반클래스 extends 추상클래스

class Car extends AbClass{}

→ 일반클래스 implements 인터페이스 (모두 구현해라)

class Car implements Runnable {}

인터페이스의 문법

(설계의 표준 >> 구현의 강제성 >> 재정의해서 사용)

  1. 구현부 없음 : 실행 블럭이 없는 함수 : void run();

ex) move(int x, int y); → 구현하는 클래스, 실행블럭 만들고 구현

  1. 유연함
class User{

	void method(Icallable ic) { // ic 파라메타는 누구든올수있어요 
		ic.m();}
	/*
	void method (D d) {
		d.m(); }
	void method(F f) {
		f.m();}
*/
}

instanceof 연산자

→ 참조변수가 참조하는 인스턴스의 실제 타입을 체크하는데 사용

→ 연산결과는 turn, false

Issues - 로그인, 메뉴 잘못입력 시 초기화면 돌아가는 선택지 만들기

1. UserSystem - SignUp

수정사항

  • 각각 반복이 되어야 하기 때문에 기존에 하나로 합쳐져있던 signUp 메소드를 각각 나누었습니다.
void signUp() { // 휴대폰 번호 입력 반복문
            System.out.println("휴대폰 번호(ID) 입력 | 0. 초기화면");
            Matcher phone;
            this.userPhoneNum = input.nextLine().trim(); // 휴대폰번호를 받아서 공백 제거
            phone = userPhonNumPattern.matcher(this.userPhoneNum); // 패턴에 맞는지 확인
            if (this.userPhoneNum.equals("0")){
                System.out.println("초기화면으로 돌아갑니다");
            } else if (!phone.find()) { // 형식에 맞지 않으면
                System.out.println("아래 형식에 맞게 입력해 주세요"); // 재입력 문구 출력
                System.out.println("ex) 010-1234-5678");
                signUp();
            } else if (userList.containsKey(userPhoneNum)) { // userList의 key에 이미 같은 번호가 있으면
                System.out.println("이미 등록된 아이디입니다"); // 등록된 아이디라고 출력
                signUp();
            } else { // 둘 다 아니면
                signUpPwd();
            }
    }

    void signUpPwd () {// 비밀번호 입력 반복문
            System.out.println("비밀번호를 입력해주세요 | 0. 초기화면");
            System.out.println("------------------------");
            System.out.println("비밀번호 형식 : \n1. 최소 영문 하나 이상 포함\n2. 특수 문자(!@#$%^&*?_~),숫자,영문(대소문자)만 가능\n3. 6글자 ~ 8글자");
            System.out.println("------------------------");
            Matcher pwd;
            this.userPwd = input.nextLine();
            pwd = userPwdPattern.matcher(this.userPwd); // 비밀번호 입력 받아서 확인
            if(this.userPwd.equals("0")){
                System.out.println("초기화면으로 돌아갑니다");
            }
            else if (!pwd.find()) { // 패턴에 맞지 않으면
                System.out.println("비밀번호 형식을 확인하고 재입력 해주세요"); // 재입력
                signUpPwd();
            } else { // 아니면
                signUpName();
            }
    }

    void signUpName() {// 이름 입력 반복문
            System.out.println("이름을 입력해주세요 | 0. 초기화면");
            Matcher name;
            userName = input.nextLine();
            name = userNamePattern.matcher(this.userName); // 이름 입력 받은 후 형식 확인

            if(userName.equals("0")){
                System.out.println("초기화면으로 돌아갑니다");
            }
            else if (!name.find()) { // 아니면
                System.out.println("다시 한 번 이름을 입력해 주세요");// 오류 출력
                System.out.println("ex) 홍길동 ");
                signUpName();
            } else {
                userList.put(userPhoneNum, new User(userPhoneNum, userName, userPwd));
                io.writeUserList();
                showResult();
            }
    }

출력 예시

image

2. UserSystem - userLogin

수정사항

  • 기존 메소드에 if문만 하나 더 추가했습니다.
public int userLogin() {
        int cnt = 0;

        while (cnt == 0) {
            System.out.println("ID를 입력해주세요 | 0. 초기화면");
            System.out.println("ID는 휴대폰 번호입니다. (010-0000-0000)");
            userPhoneNum = input.nextLine().trim();
            Matcher phone = userPhonNumPattern.matcher(userPhoneNum);
            if (userPhoneNum.equals("0")){
                System.out.println("초기화면으로 돌아갑니다");
                break;
            }
            else if (!phone.find()) {
                System.out.println("휴대폰 번호 양식에 맞춰서 다시 입력해주세요");
                System.out.println("ex) 010-1234-5678");
                continue;
            } else if (!userList.containsKey(userPhoneNum)) {
                System.out.println("ID를 찾을 수 없습니다");
                System.out.println("다시 한 번 정확히 입력해 주세요");
                continue;
            }
            for (cnt = 3; cnt > 0; cnt--) {
                System.out.println("비밀번호를 입력해주세요");
                userPwd = input.nextLine();

                if (userList.get(userPhoneNum).getUserPwd().equals(userPwd)) {
                    System.out.println();
                    System.out.println("***************");
                    System.out.println(userList.get(userPhoneNum).getUserName() + "님, 환영합니다!");
                    System.out.println("***************");
                    System.out.println();
                    Menu.cur_user_id = userPhoneNum;
                    break;

                } else {
                    if (cnt > 1) {
                        System.out.println("입력하신 비밀번호가 잘못되었습니다");
                        System.out.print((cnt - 1) + "번의 기회가 남았습니다. 올바른 ");
                    } else {
                        System.out.println("입력하신 비밀번호가 잘못되었습니다");
                        System.out.println("처음으로 돌아갑니다");
                        return cnt;
                    }
                }
            }
        }
        return cnt + 1;
    }

출력 예시

image

3. AdminSystem - addBike()

수정사항

  • 기존 코드에 이전화면으로 돌아가기(0) 추가
  • 등록 대수 입력 시 숫자를 제외한 아무키를 누를 경우 (try/catch) 취소 처리 (이전화면)
    HashMap<String, Bike> addBike() {
        System.out.println("등록하고자 하는 자전거의 종류를 입력하세요");
        System.out.println("1. 1인용 자전거 | 2. 2인용 자전거 | 0. 돌아가기");
        while (true) {
            int input = 0;
            try {
                input = Integer.parseInt(scan.nextLine());
            } catch (NumberFormatException e) {
                System.out.println("1인용은 1번, 2인용은 2번, 이전 메뉴로 돌아가시려면 0번을 입력해 주세요");
                continue;
            }
            if (!(input == 1 || input == 2 | input == 0)) {
                System.out.println("1인용 혹은 2인용만 등록 가능합니다");
                System.out.println("1인용은 1번, 2인용은 2번, 이전 메뉴로 돌아가시려면 0번을 입력해 주세요");
            } else if (input == 0) {
                System.out.println("이전메뉴으로 돌아갑니다"); // 추가
                return null;
            } else {
                System.out.println("등록할 자전거 대수를 입력하세요 | 취소: 숫자 제외 아무키");
                int amount = 0;
                try {
                    amount = Integer.parseInt(scan.nextLine());
                } catch (NumberFormatException e) {
                    System.out.println("자전거 등록이 취소되었습니다");
                    System.out.println("이전 메뉴로 돌아갑니다");
                    return null;
                }
                String bikeId;
                if (input == 1) {
                    for (int i = 0; i < amount; i++) {
                        bikeId = String.format("S-%04d", bikeList.size());
                        bikeList.put(bikeId, new Bike(BikeType.Single, 1000));
                        io.writeBikeList();
                        System.out.println("[" + bikeId + "가 등록되었습니다]");
                    }
                    return bikeList;
                } else {
                    for (int i = 0; i < amount; i++) {
                        bikeId = String.format("T-%04d", bikeList.size());
                        bikeList.put(bikeId, new Bike(BikeType.Twin, 2000));
                        io.writeBikeList();
                        System.out.println("[" + bikeId + "가 등록되었습니다]");
                    }
                    return bikeList;
                }
            }
        }
    }

출력 예시

image

4. AdminSystem - removeBike()

수정사항

  • 기존 코드에 돌아가기(0번) 기능 추가
  • 삭제 일련번호 입력 시 취소 기능 추가
  • 특정 자전거 삭제 메서드 분리
   void removeBike() {
        io.loadRentList();
        int menu = 0;
        try {
            scan = new Scanner(System.in);
            System.out.println("원하는 삭제 방법을 선택해 주세요");
            System.out.println("1. 특정 자전거 삭제 | 2. 일괄 삭제 | 0. 돌아가기");
            menu = Integer.parseInt(scan.nextLine());
        } catch (NumberFormatException e) {
            System.out.println("숫자만 입력 가능합니다");
        }
        if (!(menu == 1 || menu == 2 | menu == 0)) {
            System.out.println("잘못 입력하셨습니다");
        } else if (menu == 0) {
            System.out.println("이전메뉴로 돌아갑니다"); // 추가
        }
        else if (bikeList.isEmpty()) {
            System.out.println("등록된 자전거가 없습니다."); // 수정
        } else if (menu == 2) {
            for (Map.Entry<String, Bike> entrySet : bikeList.entrySet()) {
                if (entrySet.getValue().getRentalStatus().equals(RentalStatus.UNAVAILABLE)) {
                    System.out.println("대여중인 자전거가 있습니다");
                    System.out.println("자전거를 모두 반납 후 시도해 주세요");
                    break;
                } else {
                    bikeList.clear();
                    System.out.println("리스트가 초기화 되었습니다");
                    io.writeBikeList();
                    break;
                }
            }
        } else removeById();
    }

    void removeById() {
        while (true) {
            String id = null;
            try {
                System.out.println("삭제 하고자 하는 자전거의 일련번호를 입력해 주세요");
                id = scan.nextLine();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            if (id.equals("0")){
                System.out.println("삭제가 취소되었습니다.");
                break;
            }
            else if (!bikeList.containsKey(id)) {
                System.out.println("일치하는 자전거가 없습니다 | 0. 취소");
            } else if (bikeList.get(id).getRentalStatus().equals(RentalStatus.UNAVAILABLE)) {
                System.out.println("해당 자전거는 대여중 입니다 | 0. 취소");
            } else {
                bikeList.remove(id);
                System.out.println(id + " 자전거가 삭제되었습니다");
                io.writeBikeList();
                break;
            }
        }
    }

###출력 예시
image

5. AdminSystem - adminLogin() / Menu - displayDefaultMenu()

  • 기존 코드에 ID 입력 및 비밀번호 입력 화면에서 초기화면 돌아가기 추가
  • 디폴트 메뉴 메서드에 3번 변수 a > '성공여부'로 변수명 변경
  • adminLogin 성공시만 true 값 반환받아 adminMenu 출력되도록 수정
boolean adminLogin() {
        String id;
        String pwd;
        while (true) {
            System.out.println("관리자 ID | 0. 초기화면");
            id = scan.nextLine().trim().toLowerCase();
            if (id.equals("0")) {
                System.out.println("초기화면으로 돌아갑니다"); // 돌아가기 추가
                return false;
            } else if (!adminMap.containsKey(id)) {
                System.out.println("ID가 맞지 않습니다. 재입력 해주세요");
            } else break;
        }
            System.out.println("관리자 비밀번호를 입력해주세요 | 0. 초기화면");
            pwd = scan.nextLine().trim();
            if (pwd.equals("0")) {
                System.out.println("초기화면으로 돌아갑니다");
            } else if (adminMap.get(id).equals(pwd)) {
                System.out.println("관리자 인증이 완료되었습니다!");
                return true;
            } else {
                System.out.println("비밀번호가 맞지 않습니다. 재입력 해주세요");
                adminLogin();
            } return false;
        }
public void displayDefaultMenu() { // 첫 메뉴 번호입력
        // 회원가입, 사용자 인증, 관리자 인증, 프로그램 종료
        while (true) {
            System.out.println();
            System.out.println("******비트를 타쇼 자전거 대여 시스템******");
            System.out.println("     원하는 메뉴의 번호를 입력하세요");
            System.out.println("        1. 회원 가입");
            System.out.println("        2. 사용자 인증");
            System.out.println("        3. 관리자 인증");
            System.out.println("        4. 프로그램 종료");
            System.out.println("**********************************");
            int menu;
            do {
                try {
                    menu = Integer.parseInt(input.nextLine());
                    if (menu >= 1 && menu <= 4) {
                        break;
                    } else {
                        throw new Exception("메뉴 번호 오류");
                    }

                } catch (Exception e) {
                    System.out.println("오류발생: " + e.getMessage());
                    System.out.println("1~4 중 다시 입력해주세요");
                }
            } while (true);

            switch (menu) {
                case 1:
                    userSystem.signUp();
                    break;
                case 2: // 변수명 수정
                    int isSuccess = userSystem.userLogin();
                    if (!(isSuccess == 1)) {
                        displayUserMenu();
                    }
                    break;
                case 3: // 로직 수정
                    if((adminSystem.adminLogin())) {
                        displayAdminMenu();
                    }
                    break;
                case 4:
                    System.out.println("이용해주셔서 감사합니다!");
                    return;
            }

        }
    }

출력 예시

image
image

Class User - 회원가입 수정 (패턴 추가)

private Pattern userPhonNumPattenrn = Pattern.compile("^01(0|1|6|7|8|9)-\\d{3,4}-\\d{4}$");
    private Pattern userNamePattern = Pattern.compile("^[가-힣]{3}$");
    private Pattern userPwdPattern =Pattern.compile("^(?=.[a-zA-Z])[0-9a-zA-Z!@#$%^&?_~]{6,8}$"); 

    private Time time;
    private RentSystem rentSystem;

    static HashMap<String,User> userList = new HashMap<String,User>();

    public User() {
        input = new Scanner(System.in);
        rentSystem = new RentSystem();
        time = new Time();
    }

    public User(String userPhoneNum, String userName, String userPwd) {
        this.userPhoneNum = userPhoneNum;
        this.userName = userName;
        this.userPwd = userPwd;
    }


////System
    HashMap singUp() {
        System.out.println("휴대폰 번호(ID) 입력");
        this.userPhoneNum = input.nextLine().trim();

        Matcher phone = userPhonNumPattenrn.matcher(this.userPhoneNum);

        if (phone.find() == false) {
            System.out.println("형식오류. 재입력");
            System.out.println("ex) 010-1234-5678");

        } else if (userList.containsKey(userPhoneNum)) {
            System.out.println("이미 등록된 아이디입니다.");
        } else {
                System.out.println("비밀번호를 입력해주세요");
                 System.out.println("비밀번호 형식 : \n<최소 영문 하나 이상 포함\n 특수 문자(!@#$%^&*?_~),숫자,영문(대소문자)만 가능\n6글자 ~ 8글자>");
                this.userPwd = input.nextLine();

            Matcher pwd = userPwdPattern.matcher(this.userPwd);

            if (pwd.find() == false) {
                System.out.println("형식 오류. 재입력");
            }else {
                System.out.println("이름 입력");
                this.userName = input.nextLine();


                Matcher neme = userNamePattern.matcher(this.userName);
                if (neme.find() == false) {
                    System.out.println("형식 오류. 재입력");
                    System.out.println("ex) 홍길동 ");

                } else {
                    this.userList.put(this.userPhoneNum, new User(this.userPhoneNum, this.userName, this.userPwd));
                }
                    rentSystem.writeUserList();
                    showResult();
                }
            }
        return userList;
    }

Issues - 가입된 사용자가 없는 경우, 가입된 회원이 없습니다라고 출력된다.

이슈사항

가입된 사용자가 없는 경우, 가입된 회원이 없습니다라고 출력된다.
(회원목록조회)

IO.void readUserList()

  • 출력 조건문 추가하였습니다.
System.out.println("=====================비트를 타쇼 회원 리스트=====================");

            for (Map.Entry<String,User> entrySet : UserSystem.userList.entrySet()) {
                System.out.println(entrySet.getValue());
            }

            if(UserSystem.userList.size() == 0) System.out.println("가입된 회원이 없습니다.");

            System.out.println("===============================================================");

image

Issues - 등록된 자전거가 없을 경우 출력

이슈사항

등록된 자전거가 없을 경우, "등록된 자전거가 없습니다"라고 출력한다 (자전거 목록 조회, 자전거 삭제)

자전거 삭제

  • 이미 코드가 존재하여서 안에 문구수정만 해보았습니다.
void removeBike() {
        io.loadRentList();
        Scanner scan = new Scanner(System.in);
        System.out.println("원하는 삭제 방법을 선택해 주세요");
        System.out.println("1. 특정 자전거 삭제 | 2. 일괄 삭제");
        int menu = Integer.parseInt(scan.nextLine());
        if (!(menu == 1 || menu == 2)) {
            System.out.println("잘못 입력");
        } else if (bikeList.isEmpty()) {
            // System.out.println("삭제할 자전거가 없습니다.");
           System.out.println("등록된 자전거가 없습니다.");

image

자전거 목록 조회

*등록된 자전거가 없습니다 문구 추가하였습니다.

void readBikeList () {
        File file =new File(fileRoot+"bikelist.txt");
        FileInputStream fis =null;
        BufferedInputStream bis =null;
        ObjectInputStream ois =null;

        try{
            fis =new FileInputStream(file);
            bis =new BufferedInputStream(fis);
            ois =new ObjectInputStream(bis);

            bikeList = (HashMap<String, Bike>) ois.readObject();

            System.out.println("====== 비트를 타쇼 자전거 등록 리스트 ======");

            for (Map.Entry<String,Bike> entrySet : bikeList.entrySet()) {
                System.out.println("["+entrySet.getKey()+"]" + entrySet.getValue());
            }

            if(bikeList.size() == 0) { // 양수진 - 수정
                System.out.println("등록된 자전거가 없습니다.");
                }

            System.out.println("========================================");

image

image

class AdminSystem - 최대 한도 이상의 자전거 등록 시도 처리

	HashMap<String, Bike> addBike() {
		Scanner scan = new Scanner(System.in);
		System.out.println("등록하고자 하는 자전거의 종류를 입력하세요");
		System.out.println("1. 1인용 자전거 | 2. 2인용 자전거");
		try {
			int input = Integer.parseInt(scan.nextLine());
			if (!(input == 1 || input == 2)) {
				System.out.println("1인용 혹은 2인용만 등록 가능합니다");
				System.out.println("1인용은 1번, 2인용은 2번을 입력해 주세요");
			} else {
				System.out.println("등록할 자전거 대수를 입력하세요");
				int amount = Integer.parseInt(scan.nextLine());
				String bikeId;
				if (((bikeList.size()) + (amount)) > 100) {
					System.out.println("자전거는 최대 100대까지만 등록할 수 있습니다");
					System.out.println("현재 등록된 자전거: " + bikeList.size() + "대");
				} else if (input == 1) {
					for (int i = 0; i < amount; i++) {
						bikeId = String.format("S-%04d", bikeList.size());
						bikeList.put(bikeId, new Bike(BikeType.Single, 1000));
						io.writeBikeList();
						System.out.println("[" + bikeId + "가 등록되었습니다]");
					}
				} else {
					for (int i = 0; i < amount; i++) {
						bikeId = String.format("T-%04d", bikeList.size());
						bikeList.put(bikeId, new Bike(BikeType.Twin, 2000));
						io.writeBikeList();
						System.out.println("[" + bikeId + "가 등록되었습니다]");
					}
				}
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
			System.out.println("잘못 입력");
		}
		return bikeList;
	}

7/28 수업 내용 정리

✨ 추상 클래스 (Abstract Class)

➡️ 문법 : abstract class 클래스이름

  • 추상 메서드를 포함한 클래스
  • 인스턴스 생성 불가
  • 생성자, 멤버변수, 메서드는 포함
  • 반드시 상속을 해서 자손 클래스에서 완성 시켜 줘야 함

추상클래스의 역할

  • 새로운 클래스를 작성하는데 있어서 바탕이 되는 조상클래스
  • 클래스들의 공통부분을 그린 미완성 설계도를 그려놓고 나중에 각 설계도를 완성하는 방식

✨ 추상 메서드 (Abstract Method)

image

추상 메서드는 위 이미지의 메서드의 구성 요소 중 선언부 만 작성한다 (마칠때 세미콜론(;) 포함)
주석으로는 어떤 기능을 수행할 목적으로 작성하였는지 설명한다

구현부 인 메서드 내용은 추상클래스를 상속 받는 자손클래스에서 overriding을 통해 재정의를 해서 사용한다.

즉, 해당 추상 클래스를 상속받은 자손 클래스는 반드시 클래스 내에 있는 추상 메서드를 전부 재정의(overriding) 해줘야만 사용이 가능하다


✨ 인터페이스 (Interface)

➡️ 문법 : interface 인터페이스 이름 { 인터페이스 내용 }

인터페이스는 일종의 추상 클래스이다. 추상클래스 보다 추상화 정도가 높은 추상 메서드를 가지고 있는 클래스의 일종이라고 생각하면 된다.

인스턴스만 생성 불가이고, 생성자, 멤버변수, 메서드는 얼마든지 넣어도 되는 추상 클래스와 달리 인터페이스가 가질 수 있는 것은 단 2개이다.

  • 상수
  • 추상 메서드

어차피 인터페이스 안에는 위 2가지만 쓸 수 있기 때문에 상수랑 추상 메서드 앞에 길게 붙는 수식어들(아래 괄호 안)을 생략할 수 있다.

(public static final) [타입] [상수이름] = [값];
(public abstract) [메서드이름] ([매개변수]);

인터페이스가 특이한 점은, 다중상속이 가능하다는 것이다.

interface Movable {
			void move (int x, int y);
}

interface Attackable {
			void attck (Unit u);
}

interface Fightable extends Movable, Attackable { 
			// 위의 인터페이스 2개를 상속 받았으므로, 이 안에서는
			// move(), attack() 메소드를 쓸 수 있다 (멤버로 가진다)
 }

인터페이스는 추상 클래스와 마찬가지로 인스턴스를 생성할 수 없고, 다른 클래스에서 인터페이스를 받아서 메소드를 완성해 줘야 한다.

image

이렇게 다른 클래스에서 인터페이스를 받아 쓸 때는, 상속과 마찬가지로 클래스 이름 뒤에 implements 를 붙이고 인터페이스 이름을 넣어주면 된다. 이 때 이런 것을 [인터페이스 이름]이 [클래스 이름]을 구현한다고 말한다.

위 이미지 같이 상속과 구현을 동시에 하는 것도 가능하다.

인터페이스 이름은 어떠한 기능 또는 행위를 하는데 필요한 메소드를 제공한다는 의미를 강조하기 위해서Fightable 과 같이 ~할 수 있는 이라는 뜻을 가진 able을 붙이는 것이 일반적이다.

class Unit { int currentHP, x, y; }

interface Movable {
			void move (int x, int y);
}

interface Attackable {
			void attack (Unit u);
}

interface Fightable extends Movable, Attackable { 
			// 위의 인터페이스 2개를 상속 받았으므로, 이 안에서는
			// move(), attack() 메소드를 쓸 수 있다 (멤버로 가진다)
 }

class Fighter extends Unit implements Fightable {
			public void move (int x , int y) { 함수 내용  }
			public void attack (Unit u) { 함수 내용 }
}

위의 코드를 도식화 하면 아래 그림과 같다.

image

Fightable 인터페이스는 MovableAttackable 인터페이스를 다중상속 받았기 때문에 Fighter 클래스는 Fightable 인터페이스만 구현했지만, move();attack(); 메소드를 모두 가져와서 완성시킬 수 있었다.

이 때, 주목해야할 점은 Fighter 클래스에서 두 메소드를 완성시킬 때 public 이 사용되었다는 것이다. 이 이유는, 인터페이스에 들어가는 모든 메소드에는 앞서 말했다시피, public abstract이 생략 되었기 때문이다.

이와 같이 인터페이스는 다중 상속이 가능하지만 실제로 인터페이스를 통해 다중 상속을 구현하는 경우는 거의 없다. 굳이 다중 상속을 해야할 경우에는 보통 두 조상 클래스 중에서 비중이 높은 쪽을 선택하여 구현하고 다른 한 쪽은 클래스 내부에 멤버로 포함 시키거나 필요한 부분만 뽑아서 포함 시키는 것이 바람직하다.


✨ 다형성의 활용 (Interface의 형변환, instanceof 연산자 활용)

인터페이스 타입으로 형변환 하는 것을 알아보기 전에, 며칠 전에 배웠던 다형성과 참조변수의 형번환을 다시 복습해보자.

객체지향개념에서 다형성 이란?
조상클래스 타입의 참조변수자손클래스의 인스턴스를 참조할 수 있는 것

class Tv {
		boolean power;
		int channel;

		void power() { power = !power; }
		void channelUp() { ++channel; }
		void channelDown() { --channel; }
}

class CaptionTv extends Tv {
		String text;
		void caption() { /*내용생략*/ }
}

public class Exercise {
	public static void main(String[] args) {
			Tv       t     =   new CaptionTv();
	//조상class	참조변수     인스턴스   자손타입
	// -> 조상 타입의 참조변수로 자손 인스턴스를 참조

	CaptionTv c = new CaptionTv();
	Tv t = (Tv) c;
	// 위 두 줄을 합치면 Tv t = new CaptionTv();가 된다	
	}
}

위와 같이 CaptionTvTv를 상속할 때, Tv 타입의 참조변수로 CaptionTv 타입의 인스턴스를 참조할 수 있는 것이다. 이 때, 참조변수 tCaptionTv 에 있는 인스턴스 중, Tv 에서 정의된 멤버들만 사용할 수 있다. (String textcaption() 은 사용하지 못함)

참조변수들은 상속 관계가 있을 때, 형변환으로 부모 타입이나 자식 타입으로 변신할 수 있다. 이때, 자손타입에서 부모타입은 (부모타입) 이라는 캐스팅 연산자를 생략 가능하지만, 부모타입에서 자손타입은 생략이 불가하다.

image

👶🏻 ➡️ 👵🏻  : 형변환 생략가능 
👵🏻 ➡️ 👶🏻 : 형변환 생략불가 
🤷‍♀️ WHY? →  
자손타입이 더 포함하고 있는 내용이 많기 때문에 (내꺼도 내꺼, 니꺼도 내꺼) 

애초에 형변환은 왜 하는 걸까?
형변환은 참조변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에 참조변수의 형변환은 인스턴스에 아무런 영향을 미치지 않는다.
단지 참조변수의 형변환을 통해서 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위(개수)를 조절하는 것 뿐이다.

서로 상속관계에 있는 타입 간의 형변환은 양방향으로 자유롭게 수행될 수 있으나, 참조변수가 가리키는 인스턴스의 자손타입으로 형변환은 허용되지 않는다. 그래서 참조변수가 가리키는 인스턴스의 타입이 무엇인지 확인하는 것이 중요하다.

이때 쓰는 것이 연산자 instanceof 이다. instanceof는 참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아볼 수 있다. 주로 조건문(if)에서 쓰이며, 결과값은 true/false로 반환된다.

if ( 참조변수 instanceof 타입명 ) {
					타입명 변수명 = (타입명) 참조변수;
					// 형변환이 가능할 때(true), 형변환을 하는 구문
	} 

instanceof 는 구체적으로 다음과 같은 상황일 때 쓰일 수 있다.

void doWork(Car c) {
			if (c instanceof FireEngine) {
					FireEngine fe = (Fireengine) c;
					fe.water();
			} else if (c instanceof Ambulance) {
					Ambulance a = (Ambulance) c;
					a.siren();
			}
}

/* ... */

public class Exercise {
	public static void main(String[] args) {
				doWork(c);
				// 여기서 매개변수를 입력 했을 때, c의 클래스가 
			  // Car클래스일지, Car클래스의 자손클래스일지 모름
		}
}

예제에서 보면, doWork 함수에서 매개변수로 Car 타입의 참조변수 c 를 받고 있다. 이 함수가 실제로 메인 함수에서 쓰였을 때, 매개변수로 입력될 수 있는 것은 Car 클래스 및 Car 클래스의 자손 클래스를 타입으로 가지는 인스턴스 이다. 그러므로, 매개변수로 입력되는 것(인스턴스)이 FireEngine 타입으로 형변환이 가능할지 모르는 것이다.

이럴 때는 무작정 형변환을 시도하는 것이 아닌, instanceof로 형변환이 가능한지 체크를 해주고 형변환을 진행해야 한다.

class Unit { int currentHP, x, y; }

interface Movable {
			void move (int x, int y);
}

interface Attackable {
			void attck (Unit u);
}

interface Fightable extends Movable, Attackable { 
			// 위의 인터페이스 2개를 상속 받았으므로, 이 안에서는
			// move(), attack() 메소드를 쓸 수 있다 (멤버로 가진다)
 }

class Fighter extends Unit implements Fightable {
			public void move (int x , int y) { /*함수 내용*/  }
			public void attack (Unit u) { /*함수 내용*/ }
}

public class Exercise {
	public static void main(String[] args) {
			
			Fightable f = (Fightable) new Fighter();
								/*또는*/
			Fightable f = new Fighter();
	}
}

다시 인터페이스 얘기로 돌아와서, 인터페이스를 구현한 클래스는 인터페이스를 부모 클래스로 둔 자손 클래스라고도 볼 수 있다. 따라서 위 코드에서 보면 Fightable타입의 참조변수로 Fighter 인스턴스를 호출한 것을 알 수 있다. (단, 참조변수로는 인터페이스 Fightable에 정의된 멤버만 가능하다.)

인스턴스를 참조할 수 있으니까, 매개변수로도 쓸 수 있다.

void attack (Fightable f) { /*함수내용*/ }
			/*또는 함수 호출 시에 아래와 같이도 사용 가능*/
attack(new Fighter());

이렇게. 아래와 같이 리턴타입으로 지정하는 것도 가능하다.

Fightable method() {
			/* 함수 내용 */
		Fighter f = new Fighter();
		return f;
		// 위 두 문장을 한 문장으로 합치면
		return new Fighter();
}

이런 식으로.

이는 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.
→ 풀어쓰면, Fightable 이 리턴 타입이다 = Fighter 클래스의 인스턴스를 리턴하는 거나 마찬가지라는 얘기.

이렇게 인터페이스의 다형성은 아래 예제처럼도 활용될 수 있다.

interface Parseable {
    // 구문 분석 작업을 수행한다.
    public abstract void parse (String fileName);
}

class ParserManager {
    // 리턴 타입이 Parseable 인터페이스
    public static Parseable getParser(String type) {
        if (type.equals("XML")) {
            return new XMLParser();
        } else {
            Parseable p = new HTMLParser();
            return p;
            // return new HTMLParser();
        }
    }
}

class XMLParser implements Parseable {

    @Override
    public void parse(String fileName) {
        /* 구문 분석 작업을 수행하는 코드를 적는다 */
        System.out.println(fileName + "- XML parsing completed");
    }
}

class HTMLParser implements Parseable {

    @Override
    public void parse(String fileName) {
        /* 구문 분석 작업을 수행하는 코드를 적는다 */
        System.out.println(fileName + "- HTML parsing completed");
    }
}

public class Interface_ParserTest {
    public static void main(String[] args) {
        Parseable parser = ParserManager.getParser("XML");
				// parser는 XMLParser의 주소값을 갖게 된다
        parser.parse("document.xml");
        parser = ParserManager.getParser("HTML");
				// parser는 HTMLParser의 주소값을 갖게 된다
        parser.parse("document2.html");
    }
}

다음과 같다. 복잡하다.

일단, 해당 예제는 파일 확장자가 xml인지, html인지 구분하는 프로그램을 구현한 것이다.

  • Parseable 은 인터페이스로, 파일 이름을 매개변수로 받아서 분석을 하는 함수를 포함하고 있다.
  • ParserManager은 클래스로, 확장자(type)을 매개변수로 받아서 파일 확장자가 XML이면 XMLParser 클래스를 리턴하고, HTML이면 HTMLParser 클래스를 리턴하는 함수(getParser)가 들어있다.
  • 밑의 내용만 다른 두 개의 XMLParser , HTMLParser 는 인터페이스 Parseable 를 구현하는 클래스로, 인터페이스 안에 있는 parse 함수를 재정의 하여, 파일 이름 밑 구문 분석이 끝났다는 문구를 출력하는 내용을 넣어주었다 (=구현하였다).
  • main 함수 영역에서는 인터페이스 타입의 parser 객체를 만들고, getParser 함수를 호출하여 "XML"이라는 타입명을 매개변수로 넣어주었다.

image

  • 메인 함수에 있는 Parseable parser = ParserManager.getParser("XML"); 를 실행하면, parser에는 스태틱 함수인 getParser 의 실행 결과가 저장되게 된다. 즉, parserXMLParser 의 주소값을 가지게 된 것이다.

✨ 상속, 포함, 의존

  1. 상속관계 (is-a)
    우리가 여태까지 했던 부모-자식 관계
    a가 b를 상속한다 (a extends b) 라고 했을 때, a의 객체가 생성됨과 동시에 b도 메모리에 올라간다.

  2. 포함관계 (has-a)
    b는 a에 포함된다는 것은 b가 a의 부품(멤버필드)이라는 것
    클래스 안에 B b; 와 같은 형식으로 선언됨

    • 전체집합
      차 - 엔진의 관계
      → 엔진은 차 없이 존재할 수 없다
      → 생명주기가 같다 (a가 생성될 때, b도 생성된다)
    • 부분집합
      학교 - 학생의 관계
      → 학생은 학교 없이도 존재할 수 있다 (따로 생성 OK)
      → 생명주기가 다를 수 있다 (a가 생성된다고 b가 자동으로 생성되지 않음)
      → 다만, 학생은 학교 안에서 부품(멤버필드)로 사용될 수 있다
  3. 의존관계
    함수(method) 내에서 사용되는 것을 말함
    → 포함과는 다르게 부품(멤버필드)로 존재하지 않는다
    → 객체를 지역변수 또는 매개변수로 사용하는 것
    → 포함과는 다르게 함수 내에서만 사용되고 함수가 끝나면 증발
    (더 이상 객체를 참조하지 않는다)

메뉴 예외처리

package kr.or.tashow;

import java.util.Scanner;

public class Menu {
	Scanner input = new Scanner(System.in);
	User user;
	Admin admin;
	IO io;
	BikeService bikeService;
	UserSystem userSystem;
	AdminSystem adminSystem;

	public Menu() {
		user = new User();
		admin = new Admin();
		io = new IO();
		bikeService = new BikeService();
		userSystem = new UserSystem();
		adminSystem = new AdminSystem();
		io.startSystem();
	}

	public void displayDefaultMenu() { // 첫 메뉴 번호입력
		// 회원가입, 사용자 인증, 관리자 인증, 프로그램 종료
		System.out.println("*****비트를 타쇼 자전거 대여 시스템*****");
		System.out.println("원하는 메뉴의 번호를 입력하세요");
		System.out.println("1. 회원가입");
		System.out.println("2. 사용자인증");
		System.out.println("3. 관리자인증");
		System.out.println("4. 프로그램종료");
		int menu = 0;
		do {
			try {
				menu = Integer.parseInt(input.nextLine());
				if (menu >= 1 && menu <= 4) {
					break;
				} else {
					throw new Exception("메뉴 번호 오류");
				}

			} catch (Exception e) {
				System.out.println("오류발생: " + e.getMessage());
				System.out.println("1~4 중 다시 입력해주세요");
			}
		} while (true);{
			switch (menu) {
			case 1:
				userSystem.singUp();
				break;
			case 2:
				userSystem.userLogin();
				displayUserMenu();
				break;
			case 3:
				adminSystem.adminLogin();
				displayAdminMenu();			
				break;
			case 4:
				return;
			default:
				System.out.println("잘못입력");
				break;
			}
		}
	}

	private void displayAdminMenu() { // 관리자 메뉴
		// 매출관리, 회원목록조회, 자전거관리, 프로그램 종료

		System.out.println("원하는 메뉴의 번호를 입력하세요");
		System.out.println("1. 매출조회");
		System.out.println("2. 회원목록조회");
		System.out.println("3. 자전거관리");
		System.out.println("4. 이전메뉴");
		int menu = 0;
		do {
			try {
				menu = Integer.parseInt(input.nextLine());
				if (menu >= 1 && menu <= 4) {
					break;
				} else {
					throw new Exception("메뉴 번호 오류");
				}
			} catch (Exception e) {
				System.out.println("오류발생: " + e.getMessage());
				System.out.println("1~4 중 다시 입력해주세요");
			}
		} while (true);{
			while (true) {
				switch (menu) {
				case 1:
					bikeService.calculateTotalSales();
					break;
				case 2:
					io.readUserList();
					break;
				case 3:
					displayBikeMenu();
					break;
				case 4:
					return;
				default:
					System.out.println("잘못입력");
					break;
				}
			}
		}
	}

	private void displayUserMenu() { // 사용자 메뉴
		// 대여하기 (> 자전거 목록조회), 반납하기 (> 결제 및 반납), 프로그램 종료

		System.out.println("원하는 메뉴의 번호를 입력하세요");
		System.out.println("1. 대여하기 (1인용)");
		System.out.println("2. 대여하기 (2인용)");
		System.out.println("3. 결제 및 반납하기");
		System.out.println("4. 이전메뉴");
		int menu = 0;
		do {
			try {
				menu = Integer.parseInt(input.nextLine());
				if (menu >= 1 && menu <= 4) {
					break;
				} else {
					throw new Exception("메뉴 번호 오류");
				}
			} catch (Exception e) {
				System.out.println("오류발생: " + e.getMessage());
				System.out.println("1~4 중 다시 입력해주세요");
			}
		} while (true); {
			switch (menu) {
			case 1:
				bikeService.rentalBike("S");
				break;
			case 2:
				bikeService.rentalBike("T");
				break;
			case 3:
				System.out.println("반납할 자전거의 일련번호를 입력해주세요");
				String id = input.nextLine();
				bikeService.returnBike(id);
				break;
			case 4:
				return;
			default:
				System.out.println("잘못입력");
				break;
			}
		}
	}

	private void displayBikeMenu() { // 자전거 관리 메뉴 번호입력
		System.out.println("원하는 메뉴의 번호를 입력하세요");
		System.out.println("1. 자전거등록");
		System.out.println("2. 자전거삭제");
		System.out.println("3. 자전거목록조회");
		System.out.println("4. 자전거대여내역조회");
		System.out.println("5. 이전메뉴");
		int menu = 0;
		do {
			try {
				menu = Integer.parseInt(input.nextLine());
				if (menu >= 1 && menu <= 5) {
					break;
				} else {
					throw new Exception("메뉴 번호 오류");
				}
			} catch (Exception e) {
				System.out.println("오류발생: " + e.getMessage());
				System.out.println("1~5 중 다시 입력해주세요");
			}
		} while (true);{
			switch (menu) {
			case 1:
				adminSystem.addBike();
				io.writeBikeList();
				break;
			case 2:
				adminSystem.removeBike();
				break;
			case 3:
				io.readBikeList();
				break;
			case 4:
				io.readRentList();
				break;
			case 5:
				return;
			default:
				System.out.println("잘못입력");
				break;
			}
		}
	}


}

Class Bike

  • Class Bike는 데이터 클래스이므로,,
  • 여기서 메소드 만들지 않고 클래스 따로빼서 데이터 관리하는 로직 클래스를 만들고 있습니다..
  • 궁금한점 댓글 or 까톡 주세용
/*
enum 을 사용한 이유.. class를 여러개 두지 않고 간결하게 코드구성

HushMap보다는 단순한 리스트 이기 때문에 ArrayList를 사용

이 클래스는 데이터를 담을 수 있는 클래스

 */


enum BikeType {
    Single,
    Twin;
}

enum RentalStatus {
    // 대여가능
    AVAILABLE,
    // 대여중,
    UNAVAILABLE;
}

public class Bike{

    private String id; // 일련번호
    private BikeType type; // 1인용, 2인용
    private RentalStatus rentalStatus; //대여가능, 대여중
    private int price; // 가격




    Bike(String id, BikeType type, RentalStatus rentalStatus, int price) {
        this.id = id;
        this.type = type;
        this.rentalStatus = rentalStatus;
        this.price = price;

    }


    @Override
    public String toString() {
        return "Bike{" +
                "id='" + id + '\'' +
                ", type=" + type +
                ", rentalStatus=" + rentalStatus +
                ", price=" + price +
                '}';
    }

    public String getId(String s) {
        return id;
    }

    public RentalStatus getRentalStatus() {
        return rentalStatus;
    }

    public BikeType getType() {
        return type;
    }

    public int getPrice() {
        return price;
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setType(BikeType type) {
        this.type = type;
    }

    public void setRentalStatus(RentalStatus rentalStatus) {
        this.rentalStatus = rentalStatus;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

Class User

*시스템에서 중복파일 확인 후 오류 안내 기능 수정 예정

package kr.or.tashow;

import java.awt.*;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class User implements Serializable {
    private String userName;
    private String userPhoneNum;
    private String userPwd;
    Scanner input;
    HashMap<String, String> user = new HashMap<String, String>();
    Pattern pt = Pattern.compile("^01(0|1|6|7|8|9)-\\d{3,4}-\\d{4}$");


    public User() {
        this.userName = userName;
        this.userPhoneNum = userPhoneNum;
        this.userPwd = userPwd;
        input = new Scanner(System.in);
    }

    //회원가입
    public void signUp (){

        System.out.println("이름을 입력해주세요");
        this.userName = input.nextLine();
        while (true) {
            System.out.println("핸드폰 번호를 입력해주세요(ID)");
            this.userPhoneNum = input.nextLine().trim().toLowerCase();

            Matcher ch = pt.matcher(this.userPhoneNum);
            if (ch.find() == false) {
                System.out.println("형식 오류. 재입력");
                System.out.println("ex) 010-1234-5678 ");

            } else {
                if (user.containsKey(userPhoneNum)) {
                    System.out.println("존재하는 ID입니다.");
                    continue;
                }
                System.out.println("비밀번호를 입력해주세요");
                this.userPwd = input.nextLine();
                user.put(userPhoneNum, userPwd);
                break;
            }
        }
        showResult();
        return;
        //초기화면으로 돌아감
    }

    //로그인
    public void userLogin () {

        while (true) {
            System.out.println("ID를 입력해주세요");
            this.userPhoneNum = input.nextLine().trim().toLowerCase();

            Matcher ch = pt.matcher(this.userPhoneNum);
            if (ch.find() == false) {
                System.out.println("형식오류. 재입력");
                System.out.println("ex) 010-1234-5678 ");

            } else {
                System.out.println("비밀번호를 입력해주세요");
                this.userPwd = input.nextLine();

            }if (!user.containsKey(this.userPhoneNum)) {
                System.out.println("ID가 맞지 않습니다.재입력");
            } else {
                if (user.get(this.userPhoneNum).equals(this.userPwd)) {
                    System.out.println("인증 완료되었습니다");
                    break;
                } else {
                    System.out.println("비밀번호 오류입니다. 재입력");
                }
            }
        }
    }

    //대여
   public void rent () {


    }
    void chooseBike () {

    }

    void pay () {

    }

        void showResult () {   //입력받은 값을 보여주기
            System.out.println("회원가입이 완료되었습니다");
            System.out.println("*****************************************************************");
            System.out.println("\t이름 : " + this.userName + ", \tID : " + this.userPhoneNum + ",\t 비밀번호 : " + this.userPwd);
            System.out.println("*****************************************************************");
            System.out.println();
        }
    }

7/25 상속연습문제 - 정유정

/*

코드 보기 힘들면 http://colorscripter.com/s/WIa3dSz

도형 - 점 - 삼각형
차 - 물 - 녹차 (덤으로 다른차도 끓여봄)

*/

class Tea{
	String tName = "차";
	void drink() {
		System.out.println("행동: 마시다");
	}	
}

class Water{
	String component;					// 물의 성분...
	String taste;						// 물의 맛...
	

	
	Water(){							// 아무것도 안넣으면... 물맛.
		this.component = "물";
		this.taste = "물맛";		
	}
	
	Water(String taste){				// 맛을 넣으면...
		this.taste = taste;				// 넣은 맛
	}
	
	Water(String component, String taste){
		this.component = component;
		this.taste = taste;
	}
}


class GreenTea extends Tea{
	String tName;
	Tea drink;
	Water water = new Water();
	
	GreenTea(){							// 그린티에서... 물을 가져다가 차를 탄다
		tName = "녹차" ;					// 딱히 지정 안하면 녹차맛의 녹차
		water.component = "녹차";
		water.taste = "녹차맛";
	}
	
	GreenTea (String tName, String component, String taste){
		this.tName = tName ;			// 만약 이렇게 샥샥 지정하면 샥샥 들어감
		water.component = component;
		water.taste = taste;		
		
	}
}



   
public class J_0723 {

	public static void main(String[] args) {

		// 티 - 녹차 만들기... 물을 가져와서 씀
		GreenTea gt = new GreenTea();
		gt.drink();
		System.out.println("차 이름: " + gt.tName);
		System.out.println("주성분: " + gt.water.component);
		System.out.println("차 맛: " + gt.water.taste);
		System.out.println("---------------");
		
		// 티 - 녹차 만들기... 물을 가져와서 씀		
		GreenTea gt2 = new GreenTea("세작잎 녹차", "물과 찻잎", "맑고 단 맛");
		gt.drink();
		System.out.println("차 이름: " + gt2.tName);
		System.out.println("주성분: " + gt2.water.component);
		System.out.println("차 맛: " + gt2.water.taste);
		System.out.println("---------------");
		
		// 안해도 되지만 덤으로 홍차도 샥샥 끓이기
		GreenTea bt = new GreenTea("얼그레이티", "물과 티백", "홍차맛");
		bt.drink();
		System.out.println("차 이름: " + bt.tName);
		System.out.println("주성분: " + bt.water.component);
		System.out.println("차 맛: " + bt.water.taste);

	}

}

class RentSystem

    public void writeBikeList() {
        File file = new File("/Users/heewonseo/Documents/1stProject/lists/bikelist.txt");
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        ObjectOutputStream oos = null;

        try {
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            oos = new ObjectOutputStream(bos);

            oos.writeObject(Bike.bikeList);
            System.out.println("저장되었습니다.");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                oos.close();
                bos.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void readBikeList () {
        File file = new File("/Users/heewonseo/Documents/1stProject/lists/bikelist.txt");
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        ObjectInputStream ois = null;

        try {
            fis = new FileInputStream(file);
            bis = new BufferedInputStream(fis);
            ois = new ObjectInputStream(bis);

            Bike.bikeList = (ArrayList<Bike>) ois.readObject();

            // String bikeNum, String bikeType, int fee, int countSingle, int countTwin, boolean rentStatus

            for(Bike bike : Bike.bikeList) {
                System.out.println(bike);
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                ois.close();
                bis.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

write/read 함수
기본형 (ArrayList, static BikeList 기준)

해시맵이면 읽어올 때 포문이 달라짐

for (Map.Entry<String ,RentList> entrySet : RentList.rentList.entrySet()) {
            System.out.println(entrySet.getKey() + " : " + entrySet.getValue());
        }

이렇게

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.