Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

개발자입니다

[비트캠프] 44일차(9주차4일) - Java(리팩토링: 메서드 묶음으로써 클래스), myapp-07~08 본문

네이버클라우드 AIaaS 개발자 양성과정 1기/Java

[비트캠프] 44일차(9주차4일) - Java(리팩토링: 메서드 묶음으로써 클래스), myapp-07~08

끈기JK 2023. 1. 4. 18:05

com.eomcs.oop.ex02.Exam02

 

 

스태틱 필드 → 인스턴스 필드

 

① 메서드 분류 전

class 문법으로 데이터 타입 정의하거나(Score), 메서드 묶음 하는 것(Calculator) → 추상화(abstraction)

 

② 계산기능 메서드 묶음: 클래스 문법

plus ~ divide를 Calculator 클래스로 묶는다. Exam0220에서 이를 사용한다.

 

③ GRASP 패턴 : Information Expert → 계산을 수행하는 클래스에서 결과를 관리하는 것이 옳다.

Exam0230의 main()에 있는 result를 Calculator로 옮긴다.

같은 class에 소속된 static 변수나 메서드는 class명을 생략할 수 있다.

 

 

④ 클래스 변수의 한계

Calculator의 result는 static 변수로 클래스 당 한 개만 존재한다.

 

⑤ 인스턴스 변수로 전환

Calculator의 result를 non-static 필드 = 인스턴스 필드로 전환한다.

static 메서드인 plus() ~ divide() 괄호 내부에 result가 있는 인스턴스 주소 전달한다.

 

 

⑥ static 메서드 → 인스턴스 메서드 전환

result는 인스턴스 필드이다.

plus() ~ divide() 는 인스턴스 메서드이다.

abs() 는 클래스 메서드이다.

 

 

⑦ Nested 클래스 → Package member 클래스

Calculator를 별도 파일로 분리한다.

 

⑧ 패키지 분류

Calculator를 util 패키지를 만들어 집어넣는다.

 

 

 

 

# 관련된 기능(메서드)을 묶어 분류하기

 

 1) 분류 전
 2) 메서드를 클래스로 묶어 분류하기
 3) 클래스 변수 도입
 4) 클래스 변수의 한계 확인
 5) 인스턴스 변수 도입
 6) 인스턴스 메서드 활용
 7) 패키지 멤버 클래스로 분리
 8) 클래스를 역할에 따라 패키지로 분류하기

 

 

1) 분류 전

 

public class Exam0210 {

  public static void main(String[] args) {
    // 다음 식을 연산자 우선 순위를 고려하지 않고 순서대로 계산하라!
    // 2 + 3 - 1 * 7 / 3 = ?

    // 계산 결과를 담을 변수를 준비한다.
    int result = 0;

    // 메서드를 호출하여 작업을 수행하고,
    // 리턴 결과는 로컬 변수에 저장한다.
    result = plus(2, 3);
    result = minus(result, 1);
    result = multiple(result, 7);
    result = divide(result, 3);

    System.out.printf("result = %d\n", result);
  }

  static int plus(int a, int b) {
    return a + b;
  }

  static int minus(int a, int b) {
    return a - b;
  }

  static int multiple(int a, int b) {
    return a * b;
  }

  static int divide(int a, int b) {
    return a / b;
  }
}

 클래스 문법의 용도?
 1) 사용자 정의 데이터 타입 만들 때
 - 즉 새로운 구조의 메모리를 설계할 때 사용한다.
 2) 메서드를 묶을 때
 - 서로 관련된 기능을 관리하기 쉽게 묶고 싶을 때 사용한다.

 

 

2) 메서드를 클래스로 묶어 분류하기

 계산 기능과 관련된 메서드를 별도의 블록으로 분리할 때 사용하는 문법이 "클래스"이다.
 메서드를 분류해 놓으면 좋은 점?
 - 관련된 메서드가 한 클래스에 묶여 있기 때문에 소스 코드를 유지보수하기 쉬워진다.
 - 다른 프로젝트에서 메서드를 재사용 하기가 쉽다.

public class Exam0220 {

  static class Calculator {
    static int plus(int a, int b) {
      return a + b;
    }

    static int minus(int a, int b) {
      return a - b;
    }

    static int multiple(int a, int b) {
      return a * b;
    }

    static int divide(int a, int b) {
      return a / b;
    }

    static int abs(int a) {
      //
      // if (a >= 0) 
      //   return a; 
      // else 
      //   return a * -1;
      //
      return a >= 0 ? a : a * -1;
    }
  }

  public static void main(String[] args) {
    // 다음 식을 연산자 우선 순위를 고려하지 않고 순서대로 계산하라!
    // 2 + 3 - 1 * 7 / 3 = ?

    // 계산 결과를 담을 변수를 준비한다.
    int result = 0;

    // 클래스 메서드를 호출하여 작업을 수행하고,
    // 리턴 결과는 로컬 변수에 저장한다.
    result = Calculator.plus(2, 3);
    result = Calculator.minus(result, 1);
    result = Calculator.multiple(result, 7);
    result = Calculator.divide(result, 3);

    System.out.printf("result = %d\n", result);
  }
}

 

 

3) 클래스 변수 도입

 ## 클래스 변수 사용
 - 메서드들의 작업 결과를 보관할 때 사용할 변수이다.
 - 변수 선언에 static을 붙이다.
 - "스태틱 변수"라고도 부른다.
 - 클래스 변수는 new 명령으로 생성하지 않는다.
 - 클래스가 메모리에 로딩될 때 자동으로 "Method Area" 영역에 생성된다.

public class Exam0230 {

  static class Calculator {

    static int result = 0;

    static void plus(int value) {
      // 메서드 작업 결과는 클래스 변수에 보관한다.
      result += value; // result = result + value
    }

    static void minus(int value) {
      result -= value; // result = result - value
    }

    static void multiple(int value) {
      result *= value; // result = result * value
    }

    static void divide(int value) {
      result /= value; // result = result / value
    }

    // 인스턴스를 사용하지 않는 메서드라면 그냥 클래스 메서드로 두어라.
    static int abs(int a) {
      return a >= 0 ? a : a * -1;
    }
  }

  public static void main(String[] args) {

    // 다음 식을 연산자 우선 순위를 고려하지 않고 순서대로 계산하라!
    // 2 + 3 - 1 * 7 / 3 = ?

    // 계산 결과를 보관할 변수는 더이상 필요가 없다.
    // Calculator 내부에서 계산 결과를 관리한다.
    // int result = 0;

    Calculator.plus(2);
    Calculator.plus(3);
    Calculator.minus(1);
    Calculator.multiple(7);
    Calculator.divide(3);

    System.out.printf("result = %d\n", Calculator.result);
  }
}

 

 

4) 클래스 변수의 한계 확인
public class Exam0240 {

  static class Calculator {

    // 클래스 변수는 클래스가 로딩될 때 한 번 생성된다.
    static int result = 0;

    static void plus(int value) {
      result += value; // result = result + value
    }

    static void minus(int value) {
      result -= value; // result = result - value
    }

    static void multiple(int value) {
      result *= value; // result = result * value
    }

    static void divide(int value) {
      result /= value; // result = result / value
    }

    // 인스턴스를 사용하지 않는 메서드라면 그냥 클래스 메서드로 두어라.
    static int abs(int a) {
      return a >= 0 ? a : a * -1;
    }
  }

  public static void main(String[] args) {

    // 다음 두 개의 식을 분리하여 계산해 보자!
    // - 연산자 우선 순위를 고려하지 않고 순서대로 계산하라!
    // 식1) 2 + 3 - 1 * 7 / 3 = ?
    // 식2) 3 * 2 + 7 / 4 - 5 = ?

    // 클래스 변수는 오직 한 개만 존재하기 때문에
    // 여러 개의 작업을 동시에 진행할 수 없다.
    // 한 개의 식을 계산한 후에 다른 식을 계산해야 한다.

    // 식1 계산:
    Calculator.plus(2); // + 2
    Calculator.plus(3); // + 2 + 3
    Calculator.minus(1); // + 2 + 3 - 1
    Calculator.multiple(7); // + 2 + 3 - 1 * 7
    Calculator.divide(3); // + 2 + 3 - 1 * 7 / 3 = ?

    System.out.printf("result = %d\n", Calculator.result);
    // 이렇게 계산을 완료한 후 다음 식을 계산해야 한다.

    // 식2 계산:
    // 다른 식을 계산하기 전에 기존의 계산 결과를 갖고 있는
    // result 변수를 0으로 초기화시켜야 한다.
    Calculator.result = 0;

    Calculator.plus(3); // + 3
    Calculator.multiple(2); // + 3 * 2
    Calculator.plus(7); // + 3 * 2 + 7
    Calculator.divide(4); // + 3 * 2 + 7 / 4
    Calculator.minus(5); // + 3 * 2 + 7 / 4 - 5 = ?

    System.out.printf("result = %d\n", Calculator.result);
  }
}

 

 

5) 인스턴스 변수 도입
public class Exam0250 {

  static class Calculator {
    // 인스턴스 변수(= non-static 변수)
    // - 작업 결과를 개별적으로 관리하고 싶을 때 인스턴스 변수로 선언한다.
    // - 인스턴스 변수는 클래스가 로딩 될 때 만들어지지 않는다.
    // - new 명령을 사용해서 만들어야 한다.
    // - 변수 선언 앞에 static이 붙지 않는다.
    int result = 0;

    static void plus(Calculator obj, int value) {
      // 인스턴스 변수를 다루는 메서드는 작업을 수행할 때 그 인스턴스 주소를 받아야 한다.
      // result 는 더이상 클래스 변수가 아니기 때문에 직접 접근할 수 없다.
      // 오직 인스턴스 주소를 통해서만 접근 할 수 있다.
      obj.result += value;
    }

    static void minus(Calculator obj, int value) {
      obj.result -= value;
    }

    static void multiple(Calculator obj, int value) {
      obj.result *= value;
    }

    static void divide(Calculator obj, int value) {
      obj.result /= value;
    }

    // 인스턴스를 사용하지 않는 메서드라면 그냥 클래스 메서드로 두어라.
    static int abs(int a) {
      return a >= 0 ? a : a * -1;
    }
  }

  public static void main(String[] args) {

    // 다음 두 개의 식을 분리하여 계산해 보자!
    // - 연산자 우선 순위를 고려하지 않고 순서대로 계산하라!
    // 식1) 2 + 3 - 1 * 7 / 3 = ?
    // 식2) 3 * 2 + 7 / 4 - 5 = ?
    //

    // 두 개의 식을 동시에 계산하고 싶은가?
    // 그럴려면 계산 결과를 개별적으로 관리할 수 있어야 한다.
    // 다음과 같이 각 식의 계산 결과를 보관할 메모리를 준비한다.
    Calculator c1 = new Calculator(); // 식1의 계산 결과를 보관할 메모리 준비
    Calculator c2 = new Calculator(); // 식2의 계산 결과를 보관할 메모리 준비

    // 계산을 수행할 때 계산 결과를 보관할 메모리를 전달한다.
    Calculator.plus(c1, 2); // + 2
    Calculator.plus(c2, 3); // + 3

    Calculator.plus(c1, 3); // + 2 + 3
    Calculator.multiple(c2, 2); // + 3 * 2

    Calculator.minus(c1, 1); // + 2 + 3 - 1
    Calculator.plus(c2, 7); // + 3 * 2 + 7

    Calculator.multiple(c1, 7); // + 2 + 3 - 1 * 7
    Calculator.divide(c2, 4); // + 3 * 2 + 7 / 4

    Calculator.divide(c1, 3); // + 2 + 3 - 1 * 7 / 3 = ?
    Calculator.minus(c2, 5); // + 3 * 2 + 7 / 4 - 5 = ?

    // 식1의 계산 결과는 c1 인스턴스의 result 변수에 들어 있고,
    // 식2의 계산 결과는 c2 인스턴스의 result 변수에 들어 있다.
    System.out.printf("c1.result = %d\n", c1.result);
    System.out.printf("c2.result = %d\n", c2.result);
  }
}

 

 

6) 인스턴스 메서드 활용
public class Exam0260 {

  static class Calculator {
    int result = 0;

    // 인스턴스 변수를 다룰 때는 인스턴스 메서드를 사용하는 것이 편하다!
    // 왜?
    // - 인스턴스 주소를 파라미터로 받을 필요가 없기 때문이다.
    // - 메서드를 호출할 때 앞쪽에 인스턴스 주소를 지정한다. 
    //
    void plus(int value) {
      // 메서드를 호출할 때 앞쪽에 지정한 인스턴스 주소는 
      // this 라는 내장 변수에 자동으로 저장된다.
      this.result += value;
    }

    void minus(int value) {
      this.result -= value;
    }

    void multiple(int value) {
      this.result *= value;
    }

    void divide(int value) {
      this.result /= value;
    }

    // 인스턴스를 사용하지 않는 메서드라면 그냥 클래스 메서드로 두어라.
    static int abs(int a) {
      return a >= 0 ? a : a * -1;
    }
  }

  public static void main(String[] args) {
    // 다음 두 개의 식을 분리하여 계산해 보자!
    // - 연산자 우선 순위를 고려하지 않고 순서대로 계산하라!
    // 식1) 2 + 3 - 1 * 7 / 3 = ?
    // 식2) 3 * 2 + 7 / 4 - 5 = ?


    Calculator c1 = new Calculator(); // 식1의 계산 결과를 보관할 메모리 준비
    Calculator c2 = new Calculator(); // 식2의 계산 결과를 보관할 메모리 준비

    // 계산을 수행할 때 계산 결과를 보관할 메모리를 메서드 호출 앞에서 전달하라!
    // - 인스턴스 메서드를 사용하면 파라미터로 메모리 주소를 전달할 필요가 없다.
    c1.plus(2); // + 2
    c2.plus(3); // + 3

    c1.plus(3); // + 2 + 3
    c2.multiple(2); // + 3 * 2

    c1.minus(1); // + 2 + 3 - 1
    c2.plus(7); // + 3 * 2 + 7

    c1.multiple(7); // + 2 + 3 - 1 * 7
    c2.divide(4); // + 3 * 2 + 7 / 4

    c1.divide(3); // + 2 + 3 - 1 * 7 / 3 = ?
    c2.minus(5); // + 3 * 2 + 7 / 4 - 5 = ?

    // 식1의 계산 결과는 c1 인스턴스의 result에 들어 있고,
    // 식2의 계산 결과는 c2 인스턴스의 result에 들어 있다.
    System.out.printf("c1.result = %d\n", c1.result);
    System.out.printf("c2.result = %d\n", c2.result);
  }
}

 

 

7) 패키지 멤버 클래스로 분리

 Calculator 클래스를 향후 유지보수하기 쉽도록 별도의 파일로 분리한다.
 - Calculator.java 파일로 분리한다.

public class Exam0270 {

  public static void main(String[] args) {
    // 다음 두 개의 식을 분리하여 계산해 보자!
    // - 연산자 우선 순위를 고려하지 않고 순서대로 계산하라!
    // 식1) 2 + 3 - 1 * 7 / 3 = ?
    // 식2) 3 * 2 + 7 / 4 - 5 = ?

    Calculator c1 = new Calculator(); // 식1의 계산 결과를 보관할 메모리 준비
    Calculator c2 = new Calculator(); // 식2의 계산 결과를 보관할 메모리 준비

    // 계산을 수행할 때 계산 결과를 보관할 메모리를 메서드 호출 앞에서 전달하라!
    // - 인스턴스 메서드를 사용하면 파라미터로 메모리 주소를 전달할 필요가 없다.
    c1.plus(2); // + 2
    c2.plus(3); // + 3

    c1.plus(3); // + 2 + 3
    c2.multiple(2); // + 3 * 2

    c1.minus(1); // + 2 + 3 - 1
    c2.plus(7); // + 3 * 2 + 7

    c1.multiple(7); // + 2 + 3 - 1 * 7
    c2.divide(4); // + 3 * 2 + 7 / 4

    c1.divide(3); // + 2 + 3 - 1 * 7 / 3 = ?
    c2.minus(5); // + 3 * 2 + 7 / 4 - 5 = ?

    System.out.printf("c1.result = %d\n", c1.result);
    System.out.printf("c2.result = %d\n", c2.result);
  }
}

 

package com.eomcs.oop.ex02;

// 여러 곳에서 사용할 클래스라면 패키지 멤버로 만드는 것이 유지보수에 좋다.
// => 패키지 멤버 클래스
class Calculator {

  int result = 0;

  void plus(int value) {
    this.result += value;
  }

  void minus(int value) {
    this.result -= value;
  }

  void multiple(int value) {
    this.result *= value;
  }

  void divide(int value) {
    this.result /= value;
  }

  // 인스턴스를 사용하지 않는 메서드라면 그냥 클래스 메서드로 두어라.
  static int abs(int value) {
    return value >= 0 ? value : value * -1;
  }
}

 

 

8) 클래스를 역할에 따라 패키지로 분류하기

 Calculator 클래스를 향후 유지보수하기 쉽도록 별도의 패키지로 분류한다.
 - com.eomcs.oop.ex02.util 패키지를 만들어 분류한다.
 - import 를 이용하여 클래스의 패키지 정보를 지정한다.

public class Exam0280 {

  public static void main(String[] args) {
    // 다음 두 개의 식을 분리하여 계산해 보자!
    // - 연산자 우선 순위를 고려하지 않고 순서대로 계산하라!
    // 식1) 2 + 3 - 1 * 7 / 3 = ?
    // 식2) 3 * 2 + 7 / 4 - 5 = ?


    Calculator c1 = new Calculator(); // 식1의 계산 결과를 보관할 메모리 준비
    Calculator c2 = new Calculator(); // 식2의 계산 결과를 보관할 메모리 준비

    // 계산을 수행할 때 계산 결과를 보관할 메모리를 메서드 호출 앞에서 전달하라!
    // - 인스턴스 메서드를 사용하면 파라미터로 메모리 주소를 전달할 필요가 없다.
    c1.plus(2); // + 2
    c2.plus(3); // + 3

    c1.plus(3); // + 2 + 3
    c2.multiple(2); // + 3 * 2

    c1.minus(1); // + 2 + 3 - 1
    c2.plus(7); // + 3 * 2 + 7

    c1.multiple(7); // + 2 + 3 - 1 * 7
    c2.divide(4); // + 3 * 2 + 7 / 4

    c1.divide(3); // + 2 + 3 - 1 * 7 / 3 = ?
    c2.minus(5); // + 3 * 2 + 7 / 4 - 5 = ?

    System.out.printf("c1.result = %d\n", c1.result);
    System.out.printf("c2.result = %d\n", c2.result);
  }
}

 

package com.eomcs.oop.ex02.util;

// 다른 패키지에서 이 클래스와 멤버(필드 및 메서드)를 접근할 수 있도록 public 으로 공개한다.
//
public class Calculator {

  public int result = 0;

  public void plus(int value) {
    this.result += value;
  }

  public void minus(int value) {
    this.result -= value;
  }

  public void multiple(int value) {
    this.result *= value;
  }

  public void divide(int value) {
    this.result /= value;
  }

  // 인스턴스를 사용하지 않는 메서드라면 그냥 클래스 메서드로 두어라.
  public static int abs(int a) {
    return a >= 0 ? a : a * -1;
  }

}

 

 

 

JVM 메모리 영역과 변수, 메서드

 

Method Area에 Exam0280.class 가 bytecode로 로딩된다. 여기에는 클래스 정의(메서드 정의, 변수 정의)가 있다.

                         Calculator.class도 로딩된다. 여기에는 result 변수 선언문과 인스턴스 메서드, 클래스 메서드가 있다.

main() 메서드가 실행되면 JVM Stack에 main() 메서드 프레임이 만들어지고 args, c1 변수가 생성된다.

new Calculator() 로 Heap 에 Calculator의 인스턴스 생성된다. Calculator에 선언된 인스턴스 변수인 result가 생성된다. 메서드는 Heap에 없다. 이 주소 200이 c1에 저장된다.

JVM Stack 상황은 c1.plus(2); 에서 plus() 메서드 수행하는데 this에 c1 주소인 200이 들어간다. argument로 2가 value에 전달된다.

 

 

 

스태틱 변수, 인스턴스 변수, 로컬 변수

 

좌측 그림에서 다음과 같다.

스태틱 필드 : static int a;  ← 클래스가 로딩될 때 생성

인스턴스 필드 : int b;  ← new 명령 실행할 때 생성

로컬 변수 : int c;  ← 메서드가 호출될 때 성

 

① 클래스 로딩

Method Area에 Exam0100 로딩된다.

 

② 스티택 필드 생성

Method Area에 a = 0 로딩된다.

 

③ main()의 로컬 변수 생성

JVM Stack에 main() 프레임에 args, c, obj 생성된다.

 

④ new 명령으로 생성

Heap에 b 생성된다.

 

 

 

# 변수의 종류
package com.eomcs.oop.ex03;

public class Exam0100 {

  // static 필드 = 클래스 필드(변수)
  // - 클래스를 로딩할 때 Method Area 영역에 생성된다.
  // - 클래스는 단 한 번만 로딩된다.
  // - 따라서 스태틱 변수도 한 번만 생성된다.
  // - JVM을 종료할 때 메모리에서 한꺼번에 제거된다.
  static int a;

  // non-static 필드 = instance 필드
  // - new 연산자를 실행할 때 Heap 영역에 생성된다.
  // - new 연산자를 실행할 때마다 생성된다.
  // - Garbage Collector에 의해 인스턴스가 해제될 때 제거된다.
  int b;

  public static void main(String[] args /* 파라미터 = 로컬 변수 */) {

    // 로컬 변수
    // - 메서드가 호출될 때 JVM Stack 영역에 생성된다.
    // - 메서드 호출이 끝나면 제거된다.
    int c;
    c = 100;
    // <=== 현재 실행 시점
    // - Method Area: a 변수 존재
    // - JVM Stack: args, c, obj 변수 존재
    // - Heap: 아직 생성된 객체 없음

    Exam0100 obj;  // obj는 main()을 호출할 때 시작 시점에 JVM Stack에 생성된 상태이다.


    obj = new Exam0100();

    // <=== 현재 실행 시점
    // - Method Area: a 변수 존재
    // - JVM Stack: args, c, obj 변수 존재
    // - Heap: b 변수 존재

    System.out.println(c);
  }
}

 

 

 

 

myapp

 

07. 클래스 사용법 II : 데이터 타입 정의

 

App 에서 MemberHandler를 사용한다. MemberHandler에서 Prompt, Member(데이터 타입)를 사용한다.

 

회원 정보를 담은 새 데이터 타입을 정의한다. Member는 새 타입의 이름이다.

 

### 07. 클래스 사용법 II
- 클래스 문법을 사용하여 데이터 타입 설계하기
- 클래스와 인스턴스, 레퍼런스의 관계
- 레퍼런스 배열과 인스턴스를 다루는 방법
- 인스턴스의 변수에 값을 넣고 꺼내는 방법

 

package bitcamp.myapp;

import java.sql.Date;

public class MemberHandler {

  static final int SIZE = 100;
  static int count = 0;

  // 레퍼런스 배열 준비
  static Member[] members = new Member[SIZE];

  static void inputMembers() {
    for (int i = 0; i < SIZE; i++) {
      Member m = new Member();
      m.no = Prompt.inputInt("번호? ");
      m.name = Prompt.inputString("이름? ");
      m.tel = Prompt.inputString("전화? ");
      m.postNo= Prompt.inputString("우편번호? ");
      m.basicAddress = Prompt.inputString("주소1? ");
      m.detailAddress = Prompt.inputString("주소2? ");
      m.working = Prompt.inputInt("0. 미취업\n1. 재직중\n재직자? ") == 1;
      m.gender = Prompt.inputInt("0. 남자\n1. 여자\n성별? ") == 0 ? 'M' : 'W';
      m.level = (byte) Prompt.inputInt("0. 비전공자\n1. 준전공자\n2. 전공자\n전공? ");
      m.createdDate = new Date(System.currentTimeMillis()).toString();

      // 지금 금방 만든 객체에 사용자가 입력한 값을 저장한 후
      // 그 객체의 주소를 잃어버리지 않게 레퍼런스 배열에 보관해 둔다.
      members[i] = m;

      count++;

      String str = Prompt.inputString("계속 입력하시겠습니까?(Y/n) ");
      if (!str.equalsIgnoreCase("Y") && str.length() != 0) {
        break;
      }
    }

    Prompt.close();
  }

  static void printMembers() {
    for (int i = 0; i < count; i++) {
      Member m = members[i];
      System.out.printf("번호: %d\n", m.no);
      System.out.printf("이름: %s\n", m.name);
      System.out.printf("전화: %s\n", m.tel);
      System.out.printf("우편번호: %s\n", m.postNo);
      System.out.printf("주소1: %s\n", m.basicAddress);
      System.out.printf("주소2: %s\n", m.detailAddress);
      System.out.printf("재직자: %s\n", m.working ? "예" : "아니오");
      System.out.printf("성별: %s\n", m.gender == 'M' ? "남자" : "여자");

      String levelTitle;
      switch (m.level) {
        case 0: levelTitle = "비전공자"; break;
        case 1: levelTitle = "준전공자"; break;
        default: levelTitle = "전공자";
      }
      System.out.printf("전공: %s\n", levelTitle);

      System.out.printf("가입일: %s\n", m.createdDate);

      System.out.println("---------------------------------------");
    }
  }
}

 

 

 

08. 메뉴 구성 및 CRUD 구현

 

### 08. 메뉴 구성 및 CRUD 구현
- 메뉴를 통해 기능 실행을 제어하는 방법
- 객체를 변경하고 삭제하는 방법

 

package bitcamp.myapp;

public class App {

  public static void main(String[] args) {
    goMainMenu();

    System.out.println("안녕히 가세요!");

    // 프로그램이 사용한 자원 해제하기
    Prompt.close();
  } // main()

  public static void goMainMenu() {
    while(true) {
      System.out.println("1. 회원관리");
      System.out.println("9. 종료");
      int menuNo = Prompt.inputInt("메뉴> ");

      if (menuNo == 1 ) {
        MemberHandler.service();
      } else if (menuNo == 9) {
        break;
      } else {
        System.out.println("잘못된 메뉴 번호 입니다.");
      }
    }
  }

} // class App

 

package bitcamp.myapp;

import java.sql.Date;

public class MemberHandler {

  static final int SIZE = 100;
  static int count = 0;

  // 레퍼런스 배열 준비
  static Member[] members = new Member[SIZE];

  static void inputMember() {
    Member m = new Member();
    m.no = Prompt.inputInt("번호? ");
    m.name = Prompt.inputString("이름? ");
    m.tel = Prompt.inputString("전화? ");
    m.postNo= Prompt.inputString("우편번호? ");
    m.basicAddress = Prompt.inputString("주소1? ");
    m.detailAddress = Prompt.inputString("주소2? ");
    m.working = Prompt.inputInt("0. 미취업\n1. 재직중\n재직자? ") == 1;
    m.gender = Prompt.inputInt("0. 남자\n1. 여자\n성별? ") == 0 ? 'M' : 'W';
    m.level = (byte) Prompt.inputInt("0. 비전공자\n1. 준전공자\n2. 전공자\n전공? ");
    m.createdDate = new Date(System.currentTimeMillis()).toString();

    members[count++] = m;
  }


  static void printMembers() {
    System.out.println("번호\t이름\t전화\t재직\t전공");
    for (int i = 0; i < count; i++) {
      Member m = members[i];
      String levelTitle;
      switch (m.level) {
        case 0: levelTitle = "비전공자"; break;
        case 1: levelTitle = "준전공자"; break;
        default: levelTitle = "전공자";
      }
      System.out.printf("%d\t%s\t%s\t%s\t%s\n",
          m.no, m.name, m.tel,
          m.working ? "예" : "아니오",
              levelTitle);
    }
  }


  public static void service() {
    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. 삭제");
      System.out.println("0. 이전");
      int menuNo = Prompt.inputInt("회원관리> ");
  
      if(menuNo == 0) {
        break;
      } else if (menuNo == 1) {
        inputMember();
      }else if (menuNo == 2) {
        printMembers();
      } else if (menuNo >= 3 && menuNo <= 5) {
        System.out.println("작업실행!");
      } else {
        System.out.println("잘못된 메뉴 번호 입니다.");
      }
    }
  }
}

 

 

 


 

조언

 

*자바 개념잡는 코딩 책은 하루에 1~2문제 정도만 풀고 이런 메서드가 있구나 정도로만 학습하라. 메서드 외울 필요 없다.

 

 

 


 

과제

 

저녁 학습

com.eomcs.oop.ex03