선언위치에 따른 변수의 종류
변수는 클래스변수, 인스턴스변수, 지역변수 모두 세 종류가 있다.
변수의 종류를 결정짓는 중요한 요소는 '변수의 선언된 위치'이므로 변수의 종류를 파악하기 위해서는
변수가 어느 영역에 선언되었는지를 확인하는 것이 중요하다.
멤버변수를 제외한 나머지 변수들은 모두 지역변수이며,
멤버변수 중 static이 붙은 것은 클래스변수, 붙지 않은 것은 인스턴스 변수이다.
다음 예시를 봐보자.
class Variables{
int iv; //인스턴스 변수 >>클래스영역
static int cv; //클래스변수 >>클래스영역
void method(){
int lv = 0; //지역변수 >>메소드영역
}
}
1. 인스턴스 변수
클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다.
그렇기 때문에 인스턴스 변수의 값을 읽어오거나 저장하기 위해서는 먼저 인스턴스를 생성해야한다.
2. 클래스 변수
클래스 변수를 선언하기 위해서는 인스턴스 변수 앞에 static을 붙이기만 하면 된다.
인스턴스마다 독립적인 저장공간을 갖는 인스턴스변수와는 달리, 클래스 변수는 모든 인스턴스가 공통된 저장공간을
공유하게 된다.
인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다는 특징이 있으며,
클래스이름.클래스변수 와 같은 형식으로 사용한다.
프로그램 내에서 어디서나 접근할 수 있는 전역변수의 성격을 갖는다.
3. 지역변수
메소드 내에 선언되어 메소드 내에서만 사용 가능하며, 메소드가 종료되면 소멸되어 사용할 수 없게 된다.
클래스변수와 인스턴스변수
클래스변수와 인스턴스변수의 차이를 이해하기 위한 다음 실습프로그램을 살펴보자.
위의 실습프로그램에서 알 수 있듯이, 클래스변수 width, height는 Card클래스의 인스턴스를 생성하지 않고도
클래스이름.클래스변수와 같은 방식으로 사용할 수 있다.
또한, Card인스턴스인 c1, c2는 클래스변수 width와 height를 공유하기 때문에,
c1의 width와 height를 변경하면 c2의 width, height의 값이 바뀌었다.
즉, Card.width, c1.width, c2.width는 모두 같은 저장공간을 참조하므로 항상 같은 값을 갖게된다.
인스턴스변수는 인스턴스가 생성될 때 마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만,
클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.
* 클래스변수를 사용할 때는 참조변수 c1, c2를 통해서도 클래스 변수를 사용할 수 있지만
이렇게하면 클래스변수를 인스턴스변수로 오해하기 쉽기 때문에
Card.width처럼 클래스이름.클래스변수 와 같은 방식으로 사용하는 것이 좋다.
메소드
메소드는 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것이다.
기본적으로 수학의 함수와 유사하며, 어떤 값을 입력하면 이 값으로 작업을 수행해서 결과를 반환한다.
예를 들어, 제곱근을 구하는 메소드 Math.sqrt() 는 4.0을 입력하면 2.0을 결과로 반환한다.
이거 말고도 여러가지의 메소드가 있다.
우리가 자주 사용했던 println() 이나 random() 등이 있다.
이렇게 메소드를 사용하는 이유는 대표적으로 세 가지가 있다.
1. 높은 재사용성
이미 java API에서 제공하는 메소드들을 사용하면서 경험한 것처럼 한번 만들어 놓은 메소드는
몇 번이고 호출할 수 있으며, 다른 프로그램에서도 사용이 가능하다.
2. 중복된 코드의 제거
프로그램을 작성하다보면 같은 내용의 문장들이 있을 것이다.
이 반복되는 문장들을 하나로 묶어 메소드로 만들어 사용하면
수정하기도 편해 관리가 쉽고 오류의 발생도 줄어들 것이다.
3. 프로그램의 구조화
코드가 몇 줄 절도 밖에 안되는 작은 프로그램을 작성할 때에는 별 문제가 없겠지만,
몇 천 줄, 몇 만 줄이 넘는 프로그램도 main메소드 안에 모든 문장을 넣을 순 없다.
따라서 문장들을 작업단위로 나누어 여러 개의 메소드에 담아 프로그램을 구조화 할 필요가 있다.
메소드의 선언과 구현
메소드는 크게 두 부분, '선언부(header, 머리)'와 '구현부(body, 몸통)'로 이루어져 있다.
메소드는 다음과 같이 정의할 수 있다.
반환타입 메소드이름(타입변수명, 타입변수명)
{
}
int add(int a, int b)
{
int result = a + b;
return result;
}
메소드 선언부
메소드 선언부는 메소드의 이름과 매개변수 선언, 그리고 반환타입으로 구성되어 있다.
위의 메소드를 예시로 들면, int add에서 int는 반환타입이고, add는 메소드 이름이다.
그리고 int x, int y는 메소드 안에서 사용할 매개변수를 선언한 것이다.
반환타입이 없는 경우에는 'void'를 적어야 한다.
메소드 구현부
메소드의 선언부 다음에 오는 괄호를 메소드의 구현부라고 하는데,
여기에 메소드를 호출했을 때 수행될 문장들을 넣는다.
return문
메소드의 반환타입이 void가 아닌 경우, 구현부 안에 return 반환값; 이 반드시 포함되어 있어야한다.
이 때 메소드로의 입력은 여러 개일 수 있어도, 출력은 최대 하나만 허용해야 한다.
또한 반환하는 타입과 메소드 선언부에 선언했던 반환타입이 일치해야 한다.
메소드의 호출
메소드를 정의했어도 호출되지 않으면 아무 일도 일어나지 않는다.
메소드를 호출하는 방법은 다음과 같다.
메소드이름(값1, 값2 ...) ;
예를 들어 위의 add메소드를 호출한다고 하면
int result = add(3, 5) ; 이렇게하면 add메소드를 호출하여 반환값을 result에 저장한다는 뜻이다.
이 때 주의할 점은
괄호() 안에 지정해준 값들을 '인자'또는 '인수'라고 하는데,
인자의 개수와 순서는 호출된 메소드에 선언된 매개변수와 일치해야 한다.
메소드의 선언과 호출을 이용한 다음 실습프로그램을 살펴보자.
같은 클래스 내의 메소드끼리는 참조변수를 사용하지 않고도 서로 호출이 가능하지만
다른 클래스 내의 메소드를 호출할 때에는 MyMath mm = new MyMath(); 와 같이
클래스의 인스턴스를 생성한 다음 참조변수 mm을 통해 해야한다.
아까 전의 int add() 메소드에서는 매개변수의 값이 모두 int x, int y로 int형이기 때문에
호출할 때의 add(5.0, 3.0)가 불가능했다.
매개변수의 형태는 int고 호출할 때의 인자의 형태는 float이기 때문에 에러가 발생하였다.
하지만 여기서 눈여겨 볼 것은 divide(double a, double b)를 호출하는 부분이다.
divide메소드에서 선언된 매개변수 타입은 double형인데, 이와 다른 long형의 값인 5L과 3L을 사용해서
호출하는 것이 가능하다.
호출시에 입력된 값은 메소드의 매개변수에 대입되는 값이므로,
double a = 5L; 을 수행 했을 때와 같이 자동 형변환 되어 5.0으로 변환되어 a에 저장된다.
이와 마찬가지로 add(long a, long b)메소드에도 매개변수 a, b에 int형의 값을 넣어
add(5, 3)과 같이 호출하는 것도 가능하다.
'JAVA > Basic' 카테고리의 다른 글
[JAVA-basic] 생성자 (0) | 2021.08.13 |
---|---|
[JAVA-basic] 변수와 메소드(2) (0) | 2021.08.13 |
[JAVA-basic] 클래스와 객체 (0) | 2021.08.11 |
[JAVA-basic] 다차원 배열 (0) | 2021.08.09 |
[JAVA-basic] String배열 (0) | 2021.08.06 |