Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
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
Tags
more
Archives
Today
Total
관리 메뉴

개발자입니다

[비트캠프] 40일차(8주차5일) - Java(클래스), myapp-03~06 실습 본문

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

[비트캠프] 40일차(8주차5일) - Java(클래스), myapp-03~06 실습

끈기JK 2022. 12. 30. 10:33

 

Date 클래스

 

System.currentTimeMillis()  ← OS의 시간 데이터를 읽어서 long 타입의 정수값을 밀리초로 리턴한다. 이 값은 1970년 1월 1일 0시 0분 0초 이후에 경과된 시간이다. new Date(밀리초) 에서 가공해서 년,월,일 데이터로 만든다.

 

today.toString() 에서 today가 년,월,일을 toString()으로 넘긴다. 이를 "yyyy-MM-dd" 형식으로 리턴한다. 시,분,초 표현에 hh:mm:ss 를 쓰기 때문에 월은 대문자로 "MM" 사용한다.

 

 

 

 

03. 키보드 입력, 변수, 조건문, 반복문

 

### 03. 키보드 입력과 변수, 조건문, 반복문
  - 키보드 입력을 받는 방법
  - 변수를 사용해 키보드 입력 값을 저장하는 방법
  - 조건문을 사용해 실행을 분기하는 방법
  - 비교 연산자를 사용하는 방법

 

package bitcamp.myapp;

import java.sql.Date;
import java.util.Scanner;

public class App {
  public static void main(String[] args) {

    // 키보드에서 입력을 받는 도구 준비
    Scanner keyScanner = new Scanner(System.in);

    System.out.print("번호? ");
    int no = Integer.parseInt(keyScanner.nextLine());

    System.out.print("이름? ");
    String name = keyScanner.nextLine();

    System.out.print("전화? ");
    String tel = keyScanner.nextLine();

    System.out.print("우편번호? ");
    String postNo = keyScanner.nextLine();

    System.out.print("주소1? ");
    String basicAddress = keyScanner.nextLine();

    System.out.print("주소2? ");
    String detailAddress = keyScanner.nextLine();

    System.out.println("0. 미취업");
    System.out.println("1. 재직중");
    System.out.print("재직자? ");
    boolean working = Integer.parseInt(keyScanner.nextLine()) == 1;

    System.out.println("0. 남자");
    System.out.println("1. 여자");
    System.out.print("성별? ");
    char gender = Integer.parseInt(keyScanner.nextLine()) == 0 ? 'M' : 'W';

    System.out.println("0. 비전공자");
    System.out.println("1. 준전공자");
    System.out.println("2. 전공자");
    System.out.print("전공? ");
    byte level = Byte.parseByte(keyScanner.nextLine()); // 0(비전공자), 1(준전공자), 2(전공자)

    Date today = new Date(System.currentTimeMillis());
    String createdDate = today.toString();

    System.out.printf("번호: %d\n", no);
    System.out.printf("이름: %s\n", name);
    System.out.printf("전화: %s\n", tel);
    System.out.printf("우편번호: %s\n", postNo);
    System.out.printf("주소1: %s\n", basicAddress);
    System.out.printf("주소2: %s\n", detailAddress);
    System.out.printf("재직자: %s\n", working ? "예" : "아니오");
    System.out.printf("성별: %s\n", gender == 'M' ? "남자" : "여자");

    String levelTitle;
    switch (level) {
      case 0: levelTitle = "비전공자"; break;
      case 1: levelTitle = "준전공자"; break;
      default: levelTitle = "전공자";
    }

    System.out.printf("전공: %s\n", levelTitle);

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

 

참고 코드

// 대소문자 구분없이 일치 여부 확인 메서드
str.equalsIgnoreCase("Y")

 

 

 

 

Method

 

기능 단위로 코드를 묶는 문법

재사용이 쉽다.

코드가 블록 단위로 정리되어 관리가 쉬워진다.

 

 

기존 기능을 유지한채 유지보수 하기 쉽게 코드를 정리하는 것: 리팩토링(refactoring)

 

 

 

여러 메서드가 변수 공유하기

 

class A { } 안에서 void m1() { } 메서드 안의 int a;는 void m2() { } 에서 접근 불가하다.

여러 메서드가 변수 공유하는 것은 블록 밖으로 변수 선언을 꺼내야 한다.

 

 

 

 

04. 배열

 

### 04. 배열 사용법
  - 배열을 이용하여 여러 개의 데이터를 저장하고 꺼내는 방법
  - 반복문을 사용하여 특정 명령 블록을 반복적으로 실행하는 방법
  - 반복을 종료하는 방법
  - final 키워드 사용법
  - 문자열 비교

 

package bitcamp.myapp;

import java.sql.Date;
import java.util.Scanner;

public class App {
  public static void main(String[] args) {

    Scanner keyScanner = new Scanner(System.in);

    final int SIZE = 100;
    int count = 0;

    int[] no = new int[SIZE];
    String[] name = new String[SIZE];
    String[] tel = new String[SIZE];
    String[] postNo = new String[SIZE];
    String[] basicAddress = new String[SIZE];
    String[] detailAddress = new String[SIZE];
    boolean[] working = new boolean[SIZE];
    char[] gender = new char[SIZE];
    byte[] level = new byte[SIZE];
    String[] createdDate = new String[SIZE];

    for (int i = 0; i < SIZE; i++) {
      System.out.print("번호? ");
      no[i] = Integer.parseInt(keyScanner.nextLine());

      System.out.print("이름? ");
      name[i] = keyScanner.nextLine();

      System.out.print("전화? ");
      tel[i] = keyScanner.nextLine();

      System.out.print("우편번호? ");
      postNo[i] = keyScanner.nextLine();

      System.out.print("주소1? ");
      basicAddress[i] = keyScanner.nextLine();

      System.out.print("주소2? ");
      detailAddress[i] = keyScanner.nextLine();

      System.out.println("0. 미취업");
      System.out.println("1. 재직중");
      System.out.print("재직자? ");
      working[i] = Integer.parseInt(keyScanner.nextLine()) == 1;

      System.out.println("0. 남자");
      System.out.println("1. 여자");
      System.out.print("성별? ");
      gender[i] = Integer.parseInt(keyScanner.nextLine()) == 0 ? 'M' : 'W';

      System.out.println("0. 비전공자");
      System.out.println("1. 준전공자");
      System.out.println("2. 전공자");
      System.out.print("전공? ");
      level[i] = Byte.parseByte(keyScanner.nextLine()); // 0(비전공자), 1(준전공자), 2(전공자)

      Date today = new Date(System.currentTimeMillis());
      createdDate[i] = today.toString();

      count++;

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

    keyScanner.close();

    System.out.println();

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

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

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

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

  } // main()
} // class App

 

참고 코드

// 값을 중간에 바꾸지 않게 하려면 final 선언해서 상수화한다.
final int SIZE = 100;

// 1970년 1월 1일 0시 0분 0초부터 지금까지 시간 차이를 millisecond로 나타낸다.
System.currentTimeMillis()

// str 값과 괄호 안의 값을 비교하는데 대소문자 구분하지 않는다.
str.equalsIgnoreCase("Y")

// Scanner 사용 완료 후 자원 절감하기 위해 종료한다.
keyScanner.close();

 

 

 

 

메서드 분류하기 → class 문법

 

class App { } 내 prompt와 Members를 분리시켜 새로운 클래스 안에 넣는다.

 

 

 

 

05. 메서드 사용법

 

 

### 05. 메서드 사용법(with static)
  - 코드를 관리하기 쉽게 기능 단위로 묶어 분리하기
  - 스태틱 메서드 간에 변수를 공유하기: static 변수 사용
  - 기존 기능을 유지한채 유지보수 하기 쉽게 코드를 정리하는 것: 리팩토링(refactoring)

 

public class App {

  // static 으로 선언한 변수는 static 멤버끼리 공유할 수 있다.
  static final int SIZE = 100;
  static int count = 0;

  static int[] no = new int[SIZE];
  static String[] name = new String[SIZE];
  static String[] tel = new String[SIZE];
  static String[] postNo = new String[SIZE];
  static String[] basicAddress = new String[SIZE];
  static String[] detailAddress = new String[SIZE];
  static boolean[] working = new boolean[SIZE];
  static char[] gender = new char[SIZE];
  static byte[] level = new byte[SIZE];
  static String[] createdDate = new String[SIZE];

  public static void main(String[] args) {

    // 코드를 메서드로 분리했으면 호출하라!
    inputMembers();

    System.out.println();

    // 코드를 메서드로 분리했으면 호출하라!
    printMembers();

  } // main()

  static void inputMembers() {
    Scanner keyScanner = new Scanner(System.in);

    for (int i = 0; i < SIZE; i++) {

      no[i] = promptInt(keyScanner, "번호? ");
      name[i] = promptString(keyScanner, "이름? ");
      tel[i] = promptString(keyScanner, "전화? ");
      postNo[i] = promptString(keyScanner, "우편번호? ");
      basicAddress[i] = promptString(keyScanner, "주소1? ");
      detailAddress[i] = promptString(keyScanner, "주소2? ");

      String title = "0. 미취업\n1. 재직중\n재직자? ";
      working[i] = promptInt(keyScanner, title) == 1;

      title = "0. 남자\n1. 여자\n성별? ";
      gender[i] = promptInt(keyScanner, title) == 0 ? 'M' : 'W';

      title = "0. 비전공자\n1. 준전공자\n2. 전공자\n전공? ";
      level[i] = (byte) promptInt(keyScanner, title);

      Date today = new Date(System.currentTimeMillis());
      createdDate[i] = today.toString();

      count++;

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

    keyScanner.close();
  }

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

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

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

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

  static String promptString(Scanner scanner, String title) {
    System.out.print(title);
    return scanner.nextLine();
  }

  static int promptInt(Scanner scanner, String title) {
    return Integer.parseInt(promptString(scanner, title));
  }

} // class App

 

참고 코드

// 외부 접근 가능하도록 static을 붙인다.
static final int SIZE = 100;

 

 

 

 

Class Participants Diagram

 

App 클래스가 MemberHandler 클래스를 사용한다. Member Handler 클래스가 Prompt 클래스를 사용한다.

 

 

 

 

06. 클래스 사용법

 

### 06. 클래스 사용법 I
  - 역할에 따라 메서드를 분류하기

 

package bitcamp.myapp;

public class App {

  public static void main(String[] args) {
    MemberHandler.inputMembers();

    System.out.println();

    MemberHandler.printMembers();
  } // main()

} // class App
package bitcamp.myapp;

import java.sql.Date;

public class MemberHandler {

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

  static int[] no = new int[SIZE];
  static String[] name = new String[SIZE];
  static String[] tel = new String[SIZE];
  static String[] postNo = new String[SIZE];
  static String[] basicAddress = new String[SIZE];
  static String[] detailAddress = new String[SIZE];
  static boolean[] working = new boolean[SIZE];
  static char[] gender = new char[SIZE];
  static byte[] level = new byte[SIZE];
  static String[] createdDate = new String[SIZE];

  static void inputMembers() {
    for (int i = 0; i < SIZE; i++) {

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

      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++) {
      System.out.printf("번호: %d\n", no[i]);
      System.out.printf("이름: %s\n", name[i]);
      System.out.printf("전화: %s\n", tel[i]);
      System.out.printf("우편번호: %s\n", postNo[i]);
      System.out.printf("주소1: %s\n", basicAddress[i]);
      System.out.printf("주소2: %s\n", detailAddress[i]);
      System.out.printf("재직자: %s\n", working[i] ? "예" : "아니오");
      System.out.printf("성별: %s\n", gender[i] == 'M' ? "남자" : "여자");

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

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

      System.out.println("---------------------------------------");
    }
  }
}
package bitcamp.myapp;

import java.util.Scanner;

public class Prompt {
  static Scanner scanner = new Scanner(System.in);

  static String inputString(String title) {
    System.out.print(title);
    return scanner.nextLine();
  }

  static int inputInt(String title) {
    return Integer.parseInt(inputString(title));
  }

  // Prompt 클래스를 다 사용한 후에 자원을 해제시킬 수 있는 메서드를 추가한다.
  static void close() {
    scanner.close();
  }
}

 

 

 

 

GRASP 패턴

 

OOP의 일반적인 설계 지침

General Responsibility(책임, 역할) Assignment(객체에 부여) Software Patterns

① Information Expert

② Low Coupling

③ High Cohesion

...

 

 

 

클래스 사용법 II

 

int no; String name; ... 에서 회원 정보를 담을 새 데이터 타입을 정의할 때 class 문법이 사용된다.

class Member { ~ } 에서 Member는 새 타입의 이름이다.

 

 

 

class로 정의한 새 타입의 메모리 준비하기

 

Member m = new Member(); 에서 new Member(); 하면 no, name, ... createdDate 가 담길 메모리가 준비된다. 주소는 200이다. new 명령으로 준비한 변수는 항상 그 타입의 기본값으로 초기화된다. 값 0, null, null, ... 가 들어간다.

↑ Member 클래스에 정의된 대로 준비한 변수들 "Member의 인스턴스(instance)"

m은 레퍼런스 변수이고 값에 주소 200 이 들어간다.

 

Member m2 = new Member(); 하면 member의 설계도에 따라 메모리 준비된다. 주소는 300이다.

m2는 레퍼런스 변수이고 값에 주소 300이 들어간다.

 

 

 

인스턴스의 각 변수에 값 넣기

 

변수 : 필드(field)

주소를 저장할 변수에 0을 넣을 때는 null 키워드를 사용한다.

null 은 문자열이 아니다. 주소가 0임을 표시하는 키워드다.

이를 Member의 인스턴스, Member의 객체, Member 설계도에 따라 준비한 메모리라 한다.

 

m.no = 100; 하면 주소 200의 변수 no에 100이 들어간다.

m.name = "홍길동"; 하면 주소 200의 변수 name에 "홍길동"이 들어간다.

 

 

 


 

조언

 

*재능자들을 믿지 말고 일반 사람의 방법을 믿어라.

*코딩할때 자기 자신이 옳은지 주저하지 말라. 우선 코드를 짜고 나서 나중에 리팩토링 하면 된다.

 

 


 

과제

 

저녁 학습

- com.eomcs.lang.ex07 (메서드)

- com.eomcs.lang.ex99 (콘솔)