변수와 메서드
class Variables{//클래스영역
int iv; //인스턴스변수
static int cv; //클래스변수(static변수, 공유변수)
void method(){ //메서드영역
int lv = 0; //지역변수
}
}
변수는 클래스변수, 인스턴스변수, 지역변수 세 종류가 있다. 변수의 종류를 결정 짓는 요소는 '변수의 선언된 위치'이므로 변수의 종류를 파악하기 위해서는 변수가 어느 영역에 선언되었는지를 확인하는 것이 중요하다.
- 멤버변수를 제외한 나머지 변수들은 모두 지역변수이다.
- 멤버변수 중 static이 붙은 것은 클래스변수, 붙지 않는 것은 인스턴스변수이다.
변수의 종류 | 선언위치 | 생성시기 |
클래스변수 (class variable) |
클래스영역 | 클래스가 메모리에 올라갈 때 |
인스턴스변수 (instance variable) |
인스턴스가 생성되었을 때 | |
지역변수 (local variable) |
클래스 영역 이외의 영역 (메서드 생성자, 초기화 블럭 내부) |
변수 선언문이 수행되었을 때 |
1. 인스턴스 변수(instance variable)
- 클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어진다.그렇기 때문에 인스턴스 변수의 값을 읽어 오거나 저장하기 위해서는 먼저 인스턴스를 생성해야한다.
인스턴스는 독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있다. 인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스 변수로 선언한다.
EX) class Student{ String name; int age; String subject[]; } ....등등
2. 클래스 변수(class variable)
- 클래스 변수를 선언하는 방법은 인스턴스변수 앞에 static을 붙이기만 하면 된다. 인스턴스마다 독립적인 저장공간을 갖는 인스턴스 변수와는 달리 클래스변수는 모든 인스턴스가 공통된 저장공간(변수)을 공유하게 된다. 한 클래스의 모든 인스턴스들이 공동적인 값을 유지해야하는 속성의 경우, 클래스변수로 선언해야 한다.
- 클래스 변수는 인스턴스변수와 달리 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다는 특징이 있으며, '클래스이름.클래스변수'와 같은 형식으로 사용한다.
예를 들어 Student클래스의 클래스변수 count를 사용하려면 'Student.count'와 같이 사용하면 된다.
클래스가 메모리에 '로딩'될 때 생성되어 프로그램이 종료될 때 까지 유지되며, public을 앞에 붙이면 같은 프로그램 내에서 어디서나 접근할 수 있는 '전역변수'의 성격을 갖는다.
3. 지역 변수(local variable)
- 메서드 내에 선언되어 메서드 내에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용할 수 없게 된다. for문 또는 while문의 블럭 내에 선언된 지역변수는 지역변수가 선언된 블럭 {} 내에서만 사용 가능하며, 블럭 {}을 벗어나면 소멸되어 사용할 수 없게 된다.
package JavaTest;
class Card{
String kind;
int number;
static int width = 100;
static int height = 250;
}
public class CardTest {
public static void main(String[] args) {
System.out.println("Card.width = " + Card.width);
System.out.println("Card.height = " + Card.height);
Card c1 = new Card();
c1.kind = "Heard";
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와 heigh를 각각 50, 80으로 변경합니다.");
c1.width = 50;
c1.height = 80;
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("Card.width = " + Card.width);
System.out.println("Card.height = " + Card.height);
- 클래스변수(static변수)는 객체생성없이 '클래스이름.클래스변수'로 직접 사용 가능하다.
c2.kind = "spade";
c2.number = 4;
- 인스턴스 변수를 변경한다.
c1.width = 50;
c1.height = 80;
- 클래스변수의 값을 변경한다.
Card클래스의 클래스변수(static변수)인 width, height는 Card클래스의 인스턴스를 생성하지 않고도 '클래스이름.클래스변수'와 같은 방식으로 사용할 수 있다. Card인스턴스인 c1,c2는 클래스변수인 width, height를 공유하기 때문에, c1의 width,height를 변경하면 c2의 width,height의 값도 바뀌게 된다. Card.width, c1.width, c2.width는 모두 같은 저장공간을 참조하므로 항상 같은 값을 갖게 된다.
인스턴스변수는 인스턴스가 생성될 때 마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 가진다. |
메서드
`메서드(method)`는 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것이다. 어떤 값을 입력하면 이 값으로 작업을 수행해서 결과를 반환한다. 그저 메서드가 작업을 수행하는데 필요한 값만 넣고 원하는 결과를 얻으면 될 뿐, 이 메서드가 내부적으로 어떤 과정을 거쳐 결과를 만들어내는지 전혀 몰라도 된다.
즉, 메서드에 넣을 값(입력)과 반환하는 결과(출력)만 알면 되는 것이다. 그래서 메서드를 내부가 보이지 않는 '블랙박스'라고도 한다.
사용하는 이유
- 높은 재사용성(reusability)
- Java API에서 제공하는 메서드들을 사용하면서 경험한 것처럼 한번 만들어 놓은 메서드는 몇 번이고 호출할 수 있으며, 다른 프로그램에서도 사용이 가능하다.
- 프로그램 구조화
- 큰 규모의 프로그램에서는 문장들을 작업단위로 나눠서 여러 개으 ㅣ메서드에 담아 프로그램의 구조를 단ㅅ군화시키는 것이 필수적이다.
- 중복된 코드의 제거
- 프로그램을 작성하다보면, 같은 내용의 문장들이 여러 곳에 반복해서 나타나곤 한다. 이렇게 반복되는 문장들을 묶어서 하나의 메서드로 작성해 놓으면, 반복되늠 문장들 대신 메서드를 호출하느 한 문장으로 대체할 수 있다. 그러면, 전체 소스 코드의 길이도 짧아지고, 변경사항이 발생했을 때 수정해야할 코드의 양이 줄어들어 오류가 발생할 가능성도 함께 줄어든다.
....
for(int i = 0; i<10; i++){
System.out.print("%d", numArr[i]);
System.out.println();
}
...중간 생략...
for(int i = 0; i<10; i++){
System.out.print("%d", numArr[i]);
System.out.println();
}
같은 내용의 코드가되면, 소스코드도 길어지고 해당 문장에서 변경사항이 발생했 을 때 여러 곳을 고쳐야 하므로 일도 많아지고 오류를 만들어낼 가능성도 높다.
static void printArr(int [] numArr){
System.out.printf("%d", numArr[i]);
System.out.println();
}
public static void main(String args[p]){
numArr[i] = (int)(Math.random() * 10);
printArr(numArr); //배열호출
...중간생략...
printArr(numArr); //배열호출
}
반복적으로 나타나는 문장들을 메서드로 만들어서 사용하면 코드의 중복이 제거되고, 변경사항이 발생했을 때 이 메서드만 수정하면 되므로 관리도 쉽고 오류의 발생 가능성도 낮아진다.
메서드의 선언과 구현
매서드는 '선언부(header)'와 '구현부(body)'로 이루어져 있다. 메서드를 정의한다는 것은 선언분와 구현부를 작성하는 것을 뜻하며 다음과 같은 형식으로 메서드를 정의한다.
반환타입 메서드이름 (타입 변수명, 타입 변수명 ...){
//메서드 호출시 수행될 코드
}
int add(int a, int b){
int result = a + b;
return result; //호출한 메서드로 결과를 반환
}
메서드 선언부
'메서드의 이름'과 '매개변수 선언' 그리고 '반환타입'으로 구성되어 있으며, 메서드가 작업을 수행하기 위해 어떤 값들을 필요로 하고 결과로 어떤 타입의 값을 반환하는지에 대한 정보를 제공한다.
int (반환타입, 출력) add(메서드이름) (int x, int y) (매개변수선언, 입력){
int result = x + y;
return result;//결과를 반환
}
메서드 add는 두 개의 정수를 입력받아, 두 값을 더한 결과를 반환한다.
메서드 선언부는 후에 변경사항이 발생하지 않도록 신중히 작성해야한다. 메서드의 선언부를 변경하게 되면, 그 메서드가 호출되는 모든 곳도 같이 변경해줘야 한다.
매개변수 선언
매개변수는 메서드가 작업을 수행하는데 필요한 값들(입력)을 제공받기 위한 것이며, 필요한 값의 개수만큼 변수를 선언하며 각 변수 간의 구분은 ',' 를 사용한다. 한 가지 주의할 점은 일반적인 변수선언과 달리 두 변수의 타입이 같아도 변수의 타입을 생략할 수 없다.
int add(int x, int y){} --------O
int add(int x, y){} ------------X
만일 값을 입력받을 필요가 없다면 괄호() 안에 아무 것도 적지 않는다. 매개변수의 개수가 많을 경우 배열이나 참조변수를 사용할 수 있다.
반환타입(return type)
메서드의 작업수행 결과(출력)인 '반환값'의 타입을 적는다. 반환값이 없는 경우 반환타입으로 'void'를 적어야 한다.
void print99DanAll(){
for(int i=1; i<10; i++){
for(int j=2; j<10; j++_{
System.out.print(j + "*" + i +"=" + (j*i) + " ");
}
Sustem.out.println();
}
}
메서드 print99DanAll은 구구단 전체를 출력하는데, 작업을 수행하는데 필요한 값도, 작업수행의 결과인 반환값도 없다. 그래서 void를 사용했다.
메서드의 구현부(method body)
메서드의 선언부 다음에 오는 괄호{}를 `메서드의 구현부` 라고 하는데, 여기에 메서드를 호출했을 때 수행될 문장들을 넣는다.
return문
메서드의 반환타입이 'void'가 아닌 경우, 구현부 {} 안에 'return 반환값;'이 반드시 포함되어 있어야 한다. 작업을 수행한 결과인 반환값을 호출한 메서드로 전달하는데, 이 값의 타입은 반환타입과 일치하거나 적어도 자동 형변환이 가능한 것이어야한다.
return문은 단 하나의 값만 반환할 수 있는데, 메서드로의 입력(매개변수)은 여러 개일 수 있어도 출력은 최대 하나만 허용하는 것이다.
지역변수(local variable)
매서드 내에 선언된 변수들은 그 메서드 내에서만 사용할 수 있으므로 서로 다른 메서드라면 같은 이름의 변수를 선언해도 된다. 매서드 내에 선언된 변수를 '지역변수'라고 한다.
int add(int x, int y){
int result = x + y;
return result;
}
int multiply(int x, int y){
reutrn result;
}
위에 정의된 메서드 add와 multiply에 각기 선언된 변수, x, y, result는 이름만 같을 뿐 서로 다른 변수이다.
메서드 호출
메서드를 정의했어도 호출되지 않으면 아무 일도 일어나지 않는다. 메서드를 호출해야만 구현부 {}의 문장들이 수행된다.
메서드 이름(값1, 값2);
print99danAll(); //void print99danAll()을 호출
int result = add(3,5); //int add(int x, int y)를 호출하고, 결과를 result에 저장
인자(argument)와 매개변수(parameter)
메서드를 호출할 때 괄호()안에 지정해준 값들을 '인자(argument)' 또는 '인수'라고 한다. 인자의 개수와 순서는 호출된 메서드에 선언된 매개변수와 일치해야 한다.
인자는 메서드가 호출되면서 매개변수에 대입되므로, 인자의 타입은 매개변수의 타입과 일치하거나 자동 형변환이 가능한 것이여야 한다.
add(3,5) -> add(int a, int b)
int result = add(1,2,3); // error 매서드에 선언된 매개변수의 개수가 다름
int result = add(1.0, 2.0); //error 매서드에 선언된 매개변수의 타입과 다름
위와 같이 매서드에 선언된 매개변수의 개수보다 많거나, 다른 타입의 값을 넣으면 컴파일러가 에러를 발생시킨다.
'Backend > Java' 카테고리의 다른 글
[Java] 인터페이스 상속 실습 문제 (1) | 2024.09.06 |
---|---|
[Java] JVM 메모리 구조 / JVM 수행 과정 (1) | 2024.09.05 |
[Java] Class 객체 배열 (0) | 2024.08.30 |
[Java] Class 란 / 인스턴스란 / 인스턴스의 생성과 사용 (0) | 2024.08.29 |
[디자인패턴] 프로토타입 패턴 [PPT 공유] (0) | 2023.11.21 |