본문 바로가기
네이버클라우드/JAVA 웹 프로그래밍

JAVA 10일차 (2023-06-05) 자바 기초 DAY8

by prometedor 2023. 6. 6.

ㄴ 복잡한 코드를 메서드 안에 감추는 것을 encapsulation(캡슐화)라고 함

ㄴ 캠슐화는 명령문을 사용하기 좋게 메서드 안에 코드를 숨기는 것임

 

메서드명과 클래스명 관례

ㄴ 메서드명은 보통 동사, 동사구, 전치사구(형용사구, 부사구), 명사/명사구로 정의하는데, 동사와 동사구를 90% 사용함

ㄴ 클래스명은 보통 명사, 명사구, 형용사(전치사구, 부사구)로 정의하는데, 명사와 명사구를 90% 사용함

 



클래스 접근 범위

default(package private)

ㄴ bitcamp.myapp 패키지의 App.class 와 Test.class 는 bitcamp.util 의 Calculator.class 에 접근 불가함

=> Calculator.class 의 범위가 default(package private) 이기 때문

default(package private) 는 소속된 패키지 안에서만 접근 가능

 

public

ㄴ bitcamp.myapp 패키지의 App.class 와 Test.class 는 bitcamp.util 의 Calculator.class 에 접근 가능함

=> but, Calculator.class 에 있는 init(), plus(), minus() 메소드를 call 하지 못함

public 범위는 외부 패키지의 멤버가 접근 가능

default 로 정의된 init(), plus(), minus() 등은 같은 클래스 멤버 + 같은 패키지의 클래스 멤버만이 접근 가능

 

 

패키지

ㄴ [조직].[프로젝트].[역할] 

ㄴ 조직 영역은 중복되지 않도록 도메인명을 주로 사용함

ㄴ 도메인명은 거꾸로 사용함 => com.naver, net.daum, org.apache

ㄴ 프로젝트 영역은 crm, hrd, gmail, blog 등 처럼 프로젝트 이름을 사용

ㄴ 역할 영역은 controller, service, dao, domain, util 등 처럼 특정 기능 또는 업무를 수행하는 모듈을 그룹화하거나, 계층적인 구조를 형성함

 

 

스태틱 변수와 Method Area

 java ... Test 으로 실행 시

ㄴ Method Area 에서 Test.class 를 로딩함

ㄴ Method Area 에 있는 Test.class 의 main() 이 호출됨

ㄴ JVM Stack 에서 main() 이 실행하는 동안 사용할 로컬변수를 준비함(main() 의 frame)

ㄴ Method Area 에서 Calculator.class 를 로딩함

ㄴ result 라는 스태틱 필드 생성됨 (초기화 0으로 됨)

ㄴ Method Area 에 있는 Calculator.class 의 init() 과 plus() 메서드를 call 함

ㄴ JVM Stack 에서 Calculator.init() 의 로컬변수를 준비함(Calculator.init() 의 frame)

 

클래스 로딩?

ㄴ 스태틱 변수를 생성(Method Area)

ㄴ 스태틱 블록 실행 (Static { ... })

 

실습

# 관련된 기능(메서드)을 묶어 분류하기
// 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) 메서드를 묶을 때
// - 서로 관련된 기능을 관리하기 쉽게 묶고 싶을 때 사용

 

 

 

 

클래스 및 패키지 사용법

ㄴ bitcamp.myapp.handler 패키지 안에 MemberHandler 라는 클래스 안에 inputMember(), printMembers() 메서드를 이동 (myapp 에서만 사용할 것이므로)

ㄴ bitcamp.myapp.handler 패키지 안에 MemberHandler 라는 클래스 안에 available() 이라는 메서드 추가

ㄴ bitcamp.util 패키지 안에 Prompt 라는 클래스 안에 prompt() 메서드를 inputString() 라는 이름으로 변경하여 이동 (myapp 을 제외한 다른 곳에서도 사용 가능하도록 bitcamp 패키지에 추가)

ㄴ App 클래스 안에는 printTitle(), promptContinue() 메서드가 있고, App 에서 MemberHandler 와 Prompt 클래스를 사용함

 

 

App.java

package bitcamp.myapp;

import bitcamp.myapp.handler.MemberHandler;
import bitcamp.util.Prompt;

public class App {

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

    // 회원정보 등록
    while (MemberHandler.available()) {
      MemberHandler.inputMember();
      if (!promptContinue()) {
        break;
      }
    }

    MemberHandler.printMemebers();

    Prompt.close();
  }

  static void printTitle() {
    System.out.println("나의 목록 관리 시스템");
    System.out.println("-------------------------------");
  }

  static boolean promptContinue() {
    String response = Prompt.inputString("계속 하시겠습니까?(Y/n) ");
    if (!response.equals("") && !response.equalsIgnoreCase("Y")) { // equalsIgnoreCase : 대소문자
      return false;
    }
    return true;
  }

}

 

MemberHandler.java

package bitcamp.myapp.handler;

import bitcamp.util.Prompt;

public class MemberHandler {

  static final int MAX_SIZE = 100; // 대문자로 해주는 이유 : 강조하기 위함
  static int[] no = new int[MAX_SIZE];
  static String[] name = new String[MAX_SIZE]; // java에서 []를 앞에 해주는 이유 : primitive type 변수가 아닌 레퍼런스(주소를 담는)라는 것을 알려줌
  static String[] email = new String[MAX_SIZE];
  static String[] password = new String[MAX_SIZE];
  static char[] gender = new char[MAX_SIZE];
  static int userId = 1; // 회원 번호
  static int length = 0; // 한 사람 입력 할 떄마다 증가시킬 값

  static final char MALE = 'M'; // 상수로 정의
  static final char FEMALE = 'W';

  public static void inputMember() {
    
    name[length] = Prompt.inputString("이름? ");
    email[length] = Prompt.inputString("이메일? ");
    password[length] = Prompt.inputString("암호? ");


    loop: while (true) {
      String menuNo = Prompt.inputString("성별:\n" +
      " 1. 남자\n" +
      " 2. 여자\n" +
      "> ");

      switch (menuNo) {
        case "1":
          gender[length] = MALE;
          break loop;
        case "2":
          gender[length] = FEMALE;
          break loop;
        default:
          System.out.println("무효한 번호입니다.");
      }
    }

    no[length] = userId++; // 위에서 오류가 발생할 경우 회원번호 부여하지 않기 위해(정상적인 값 입력된 경우 회원 번호를 부여)
    length++;
  }

  public static void printMemebers() {
    System.out.println("--------------------------------------------");
    System.out.println("번호, 이름, 이메일, 성별");
    System.out.println("--------------------------------------------");

    for (int i = 0; i < length; i++) {
      System.out.printf("%d, %s, %s, %c\n", no[i], name[i], email[i], gender[i]);
    }
  }

  public static boolean available() {
    return length < MAX_SIZE;
  }
}

 

Prompt.java

package bitcamp.util;

import java.util.Scanner;

public class Prompt {

  static Scanner scanner = new Scanner(System.in);
  
  public static String inputString(String title) {
    System.out.print(title);
    return scanner.nextLine();
  }

  public static void close() {
    scanner.close();
  }
}