[day07] java-basic : 메소드

3 분 소요

KeyboardTestMain.java

  • os가 속도를 빠르게 하기 위해서 버퍼라는 장치를 쓴다.
  • 이때 버퍼로 인해서 문제가 생긴다.

  • 프로그램은 RAM에 구성된 변수에 값을 넣어주거나 받는 것이 목적이다.
  • ram에 저장된 값은 외부장치를 통해서 볼 수도 있다.
  • 이때 사용되는 외부장치가 키보드, 마우스와 같은 표준 입출력장치이다.

  • 컴퓨터 내부적으로는 어떤 OS를 구성하기 위해서 기본적인 단위가 101010의 시그널 형태이다.
  • 이때 표준 입출력장치는 RAM과 문자(바이트) 단위로 정보를 주고 받는다. (Char by Char)
  • 보통 키보드를 눌렀다가 떼는 경우 정보가 넘어가는 것이다.

  • RAM에서 RAM에서 값을 넣어주는 것과 RAM에서 입출력장치로 값을 주고받는 속도는 차이가 크다.
  • 어떻게 하면 자릿수에 상관없이 속도를 비슷하게 만들 수 있는까?라는 고민에 대한 해결 방안으로 생겨난 것이 버퍼이다.

  • 버퍼는 무조건 엔터가 입력될때까지 버퍼에 값들을 모아놨다가 엔터를 치면 화면에 출력하도록 만들어 주는 것이다.
  • 표준 입출력 장치와 버퍼는 line by line으로, 버퍼와 ram은 char by char로 교환한다.
  • 예전에는 하나의 버퍼를 출력할때도 입력할때도 사용했다. 이때 플러쉬로 탈탈 버퍼를 비우고 출력을 받도, 입력이 들어오면 다시 플러쉬

  • 출력할때는 바로바로 출력되는 것처럼 보임?
  • 키보드 입력 받을 때는 line단위 버퍼로 받는다.
  • 무엇이 나오던 엔터 누를때까지 그 값을 버퍼에 다 저장을 하는 것이다.
  • 버퍼는 일종의 char배열이다.
  • 엔터나올때까지 char배열에 문자를 쭉 담기 때문이다.

  • nextInt()가 나오면, 키보드 입력을 받기 위해 버퍼가 비어있는지 먼저 확인한다.
  • 버퍼가 비어있으면 엔터 나올때까지 값을 받는다.
  • 20엔터를 입력받으면 버퍼에는 ‘2’ ‘0’ ‘\n’ 이 저장된다.
  • 숫자가 아니면 멈추고 변수에 정수값을 저장한다.
  • 그리고 버퍼를 비운다.

  • 207 57엔터을 입력받으면, 207과 57의 정수가 입력된 것으로 인식한다.

  • ‘2’ ‘0’ ‘7’ ’ ‘ ’ ‘ ’ ‘ ‘5’ ‘7’ ‘\n’
  • 정수나 실수에서는 공백이 의미가 없지만, 문자나 문자열에서는 공백도 문자로 인식하기 때문에 문제가 발생한다.
  • Scanner.nextInt 메소드는 사용자 입력의 가장 마지막 개행문자(엔터, newline)를 제거하지 않음
  • 개행문자(엔터) 전까지만 숫자로 입력 받습니다.
  • 개행문자(엔터)는 다음에 호출된 Scanner.nextLine( ) 메소드의 입력으로 처리되서 문제기 발생합니다.

메소드

  • 객체가 할 수 있는 행동을 정의
  • 자바에서는 메소드가 클래스 안에 존재해야 한다.
  • 자바에선 클래스 밖에 메소드만 존재하는 경우는 없다.
  • 자바는 완벽한 객체지향 프로그램이기 때문이다.
  • 자바에서는 변수도 클래스 밖에 존재하는 경우가 절대 없다.

  • 메소드 명명규칙 : 메서드는 소문자로 시작하는 것이 관례이다.
  • 메소드 형식 : [접근제한자] [활용제한자] 반환값 메소드명( [매개변수들] ) { 행위 기술 }
  • 메소드 예시 : public static void main(String[] args) {}
  • 반환형은 필수 요소이다. 그래서 반환형이 없다면 void를 사용한다.

  • 객체가 해야할 행동을 명시하는 것이 메소드였다.( 메소드 정의 : (고양이는) 운다 )
  • 만든 메소드를 이용해서 고양이 울어!라고 짜는 것이 중요하게 된다.
  • 모든 메소드는 클래스 안에 선언되어 있기 때문에, 메소드를 사용하기 위해서는 먼저 메소드가 정의된 클래스의 객체를 만들고 클래스객체.메소드 이름으로 호출해야 한다.

MethodMain01.java

  • 배열이 변수의 집합인것처럼, 메소드는 문장들의 집합이다.
  • 원래 메소드는 사용자의 수정 과 관련된 노가다를 줄여주기 위해 탄생했다.
*************
hello
*************
hi
*************
good bye
*************
  • 위의 문자를 반복문으로 짠다면 효율적일까? NO! => hello, hi, good bye는 규칙성이 없기 때문이다.
  • 이때, 문장들의 집합인 메소드를 활용한다면 효율적으로 수정할 수 있다.
public class MethodMain01 {

	// printStar라는 문장의 집합 정의하기
	static void printStar(){
		System.out.println("*************");
	}
	
	public static void main(String[] args) {
		
		// printStar라는 문장 실행하기
		printStar();
	}

}
  • 문장들의 집합인 메소드의 정의를 수정한다면 메소드가 실행된 코드는 수정하지 않아도 된다.
  • main메소드 내에서 정의한 메소드가 호출되면, 해당 메소드의 선언부로 가서 { 뒤의 문장을 실행하고 }을 만나면 종료하고 호출부로 돌아와 ;을 실행한다.
  • 호출한 문장을 가지고 있는 메소드를 호출자 메소드라 하고, 호출되는 메소드를 피호출자 메소드라 한다.
  • 호출자 메소드 : main() / 피호출자 메소드 : printStar()
  • 호출자 메소드 : printStar() / 피호출자 메소드 : println()

메소드의 반환값과 매개변수

  • ‘피호출자 메소드’와 ‘호출자 메소드’가 대화를 하기 위한 수단이 반환값매개변수이다.
  • 매개변수는 호출자가 피호출자에게 대화를 시도하기 위한 통로이다.
  • 매개변수로 여러개의 값을 사용하고 싶다면 ,로 연결해주거나 배열, Collection 객체를 사용하면 된다.
  • 매개변수의 데이터타입이 double이라면 묵시적 형변환이 이루어진다.

  • 반환값은 피호출자가 호출자에게 대화를 시도하기 위한 통로이다.

  • 참고 : 디버거에서 피호출자 메소드로 진입하려면 step into(f5)을 사용한다. 다시 호출자로 돌아오려면 step return(f7)을 사용한다.

  • 문서화 주석 : 메소드를 설명하려면? 문서화 주석 ( /** )을 사용해서 메소드의 기능, 파라미터, 반환값에 대해서 설명할 수 있다.

  • 반환값으로는 기본자료형 뿐 아니라 참조자료형도 반환될 수 있다.
  • ‘호출자 메소드’는 ‘피호출자 메소드’의 반환값을 대입연산자( = )를 통해서 받는다. String data = printStar('*',10);
  • 피호출자가 여러개의 값을 반환하고 싶을 때는 , 사용이 불가하다. 대신 배열이나 Collection객체를 데이터타입으로 사용해야한다.
  • 반환타입이 void가 아니라면 반드시 { } 안에 return 반환값을 선언해줘야 한다.
Random r = new Random();
int num = r.nextInt(10);
  • 위 코드를 보면 nextInt() 메소드는 Random.class에 정의되어 있으며 반환값의 데이터타입은 int, 매개변수 데이터형도 int이다.

  • System.out.println() : System.class 안에 있는 out 멤버변수의 타입은 PrintSteam이므로, println() 메소드는 PrintStream.class에 정의되어 있는 메소드이다.

메소드 오버로딩

  • 메소드 오버로딩은 같은 클래스내에 동명의 메소드이면서 매개변수의 개수 또는 타입이 다른 것이다.
  • 반환타입만 다르고 메소드명과 매개변수가 같으면 오버로딩 안된다.
  • 오버로딩된 메소드는 서로 다른 메소드로 인식된다.
  • 대표적인 메소드 오버로딩은 println()이다.
  • 크기를 가지고 있는 기본 데이터형은 묵시적 형변환이 이루어 진다.
    • 기본 데이터형의 묵시적 크기는 byte < short < int < long < float < double , char 순이다.
    • char 는 값의 범위에 음수 부분이 없기 때문에 구별해놓았고
    • float와 double은 각각 int와 long과 메모리의 크기는 같지만, 실수형은 값의 표현이 정수형과 다르므로 모든 정수형보다 실수형이 더 큰 타입이다.
  • boolean은 크기를 가지고 있지 않기 때문에 묵시적 형변환이 발생할 수 없다.
  • 같은 클래스 내의 메소드를 호출할때는 인스턴스 객체를 만들 필요가 없다. 호출메소드가 이미 객체를 생성했을 것이기 때문이다. 그리고 사실은 앞에 this.이 생략되어 있다.