class Variables
{
int iv; // 인스턴스변수
static int cv; // (static변수, 공유변수)
void method()
{
int lv = 0; // 지역변수
}
}
변수의 종류와 특징
3.2 클래스변수(class variable)와 인스턴스변수(instance variable)
class CardTest{
public static void main(String args[]){
System.out.println("Card.width = " + Card.width);
System.out.println("Card.height = " + Card.height); // 클래스변수(static변수)는 객체 생성
// '클래스이름.클래스변수'로 직접
// 사용 가능하다.
Card c1 = new Card();
c1.kind = "Heart";
c1.number = 7;
Card c2 = new Card();
c2.kind = "Spade"; // 인스턴스변수의 값을 변경한다.
c2.number = 4; // 인스턴스변수의 값을 변경한다.
System.out.println("c1은 " + c1.kind + ", " + c1.number
+ "이며, 크기는 (" + c1.width + ", " + c1.height + ")");
System.out.println("c2는 " + c2.kind + ", " + c2.number
+ "이며, 크기는 (" + c2.width + ", " + c2.height + ")");
System.out.println("c1의 width와 height를 각각 50, 80으로 변경합니다.");
c1.width = 50; // 클래스변수의 값을 변경한다.
c1.height = 80; // 클래스변수의 값을 변경한다.
System.out.println("c1은 " + c1.kind + ", " + c1.number
+ "이며, 크기는 (" + c1.width + ", " + c1.heiht + ")");
System.out.println("c2는 " + c2.kind + ", " + c2.number
+ "이며, 크기는 (" + c2.width + ", " + c2.height + ")");
}
}
class Card {
String kind; // 무늬 (인스턴스변수)
int number; // 숫자 (인스턴스변수)
static int width = 100; // 폭 (클래스변수)
static int height = 250; // 높이 (클래스변수)
}
메서드를 사용하는 이유
public static void main(String args[]){
...
for (int i = 0; i<10;i++)
numArr[i] = (int) (Math.random()*10);
for (int i = 0; i<10;i++)
System.out.printf("%d", numArr[i]);
System.out.println();
...중간 생략...
for (int i = 0;i<10;i++)
System.out.printf("%d", numArr[i]);
System.out.println();
}
static void printArr(int [] numArr) {
for(int i = 0;i<10;i++)
System.out.printf("%d", numArr[i]);
System.out.println();
}
public static void main(String args[]){
...
for(int i = 0;i<10;i++)
numArr[i] = (int) (Math.random()*10);
printArr(numArr); // 배열을 출력 (반복되는 코드 대신 메서드를 호출)
...중간 생략...
printArr(numArr); // 배열을 출력 (반복되는 코드 대신 메서드를 호출)
3. 프로그램의 구조화
몇천줄, 몇 만 줄이 넘는 프로그램도 이런 식으로 작성할 수는 없다.
큰 규모의 프로그램에서는 문장들을 작업단위로 나눠서 여러 개의 메서드에 담아 프로그램의 구조를 단순화시키는 것이 필수적이다.
public static void main(String args[]) {
int[] numArr = new int[10];
initArr(numArr); // 1. 배열을 초기화
printArr(numArr); // 2. 배열을 출력
sortArr(numArr); // 3. 배열을 정렬
printArr(numArr); // 4. 배열을 출력
}
이처럼 main메서드는 프로그램의 전체 흐름이 한눈에 들어올 정도로 단순하게 구조화하는 것이
좋다.
그래야 나중에 프로그램에 문제가 발생해도 해당 부분을 쉽게 찾아서 해결 할 수 있다.
선언부
반환타입 메서드이름 (타입 변수명, 타입 변수명, ...)
구현부
{
// 메서드 호출시 수행될 코드
}
int add(int a, int b) //선언부
//구현부
{
int result = a + b;
return result; //호출한 메서드로 결과를 반환한다.
}
메소드 선언부(method declaration, method header)
int add (int x, int y) { // 반환타입(출력) 메서드이름 (매개변수선언(입력))
int result = x + y;
return result; //결과를 반환
※ 메서드의 선언부는 후에 변경사항이 발생하지 않도록 신중히 작성해야한다. 메서드의 선언부를 변경하게 되면, 그 메서드가 호출되는 모든 곳도 같이 변경해야 하기 때문이다.
매개변수 선언(parameter declaration)
※ 일반적인 변수선언과 달리 두 변수의 타입이 같아도 변수의 타입을 생략할 수 없다
int add(int x, int y) {...} // OK
int add(int x, y) {...} // 에러, 매개변수 y의 타입이 없다.
메서드의 이름(method name)
반환타입(return type)
메소드의 구현부(method body, 메서드 몸통)
return문
int add(int x, int y)
{
int result = x + y;
return result; // 작업 결과(반환값)를 반환한다.
} //int와 result 타입 일치
지역변수(local variable)
int add(int x, int y) {
int result = x + y;
return result;
}
int multiply(int x, int y) {
int result = x * y;
return result;
}
메소드이름(값1, 값2, ...); // 메서드를 호출하는 방법
print99danAll(); // void print99danAll()을 호출
int result = add(3,5); // int add(int x, int y)를 호출하고, 결과를 result에 저장
인자(argument)와 매개변수(parameter)
public static void main(String args[ ]) {
...
int result = add(3, 5);// 3, 5 --> 인자(argument)
...
int add(int x, int y) // x, y --> 매개변수(parameter)
{
int result = x + y;
return result;
}
• 메서드에 선언된 매개변수의 개수보다 많은 값을 괄호()에 넣거나 타입이 다른 값을 넣으면 컴파일러가 에러를 발생시킨다.
int result = add(1, 2, 3); // 에러. 메서드에 선언된 매개변수의 개수가 다름
int result = add(1.0, 2.0); // 에러. 메서드에 선언된 매개변수의 타입이 다름
• 반환타입이 void가 아닌 경우, 메서드가 작업을 수행하고 반환한 값을 대입연산자로 변수에 저장하는 것이 보통이지만, 저장하지 않아도 문제가 되지 않는다.
int result = add(3, 5); // int add(int x, int y)의 호출결과를 result에 저장
add(3, 5); // OK. 메서드 add가 반환한 결과를 사용하지 않아도 된다.
class MyMathTest {
public static void main(String args []) {
MyMath mm = new MyMath();
long result1 = mm.add(5L, 3L);
long result2 = mm.substract(5L, 3L);
long result3 = mm.multiply(5L, 3L);
double result4 = mm.divide(5L, 3L);
System.out.println("add(5L, 3L) = " + result);
System.out.println("subtract(5L, 3L) = " + result2);
System.out.println("multiply(5L, 3L) = " + result3);
System.out.println("divide(5L, 3L) = " + result4);
}
}
class MyMath {
long add(long a, long b) {
long result = a+b;
return result;
// return a + b; // 위의 두 줄을 이와 같이 한 줄로 간단히 할 수 있다.
}
long substract(long a, lon b) {return a -b;}
long multiply(long a, long b) {return a * b;}
double divide(double a, double b) {return a / b;}
}
}
MyMath mm = new MyMath(); //먼저 인스턴스를 생성한다.
long value = mm.add(1L, 2L); // 메서드를 호출한다.
long add(long a, long b) {
long result = a + b;
return result;
}
void printGugudan(int dan) {
for(int i = 1; i <= 9; i++) {
System.out.printf("%d * %d = %d%n", dan, i, dan * i);
}
// return; // 반환 타입이 void이므로 생략가능, 컴파일러가 자동추가
}
int multiply(int x, int y) {
int result = x * y;
return result; // 반환타입이 void가 아니므로 생략불가
}
int max(int a, int b) {
if(a > b)
return a; // 조건식이 참일 때만 실행된다.
}
• 이런 경우 다음과 같이 if문의 else블럭에 return문을 추가해서, 항상 결과값이 반환되도록 해야 한다.
int max(int a, int b) {
if( a > b)
return a; // 조건식이 참일 때 실행된다.
else
return b; // 조건식이 거짓일 때 실행된다.
}
반환값(return value)
int add(int x, int y) {
int result = x + y;
return result;
}
int add(int x, int y) {
return x + y;
}
매개변수의 유효성 검사
float divide(int x, int y) {
// 작업을 하기 전에 나누는 수(y)가 0인지 확인한다.
if(y==0) {
System.out.println("0으로 나눌 수 없습니다.");
return 0; // 매개변수가 유효하지 않으므로 메서드를 종료한다.
}
return x / (float)y;
}