1. 클래스 변수: 멤버 변수 중 static이 붙은 것
2. 인스턴스 변수: 멤버 변수 중 static이 붙지 않은 것
3. 지역 변수: 멤버 변수를 제외한 나머지 변수
class Card {
// 인스턴스 변수 (카드마다 다름)
String kind;
int number;
// 클래스 변수 (모든 카드가 같음)
static int width = 100;
static int height = 250;
}
class CardTest {
public static void main(String args[]) {
// 클래스 변수는 인스턴스(객체) 생성없이 사용 가능하다.
System.out.println("카드의 폭:" + Card.width);
System.out.println("카드의 높이:" + Card.height);
// 인스턴스 변수를 사용하기 위해 클래스의 인스턴스(c1, c2)를 생성한다.
Card c1 = new Card();
c1.kind = "Heart";
c1.number = 7;
Card c2 = new Card();
c2.kind = "Spade";
c2.number = 4;
// c1과 c2는 클래스 변수인 width와 height를 공유하기 때문에 항상 같은 값을 갖는다.
c1.width = 50
c2.height = 80
System.out.println("c1 카드의 폭:"+ c1.width, ", c1 카드의 높이"+ c1.height);
System.out.println("c2 카드의 폭:"+ c2.width, ", c2 카드의 높이"+ c2.height);
/*
실행 결과
카드의 폭: 100
카드의 넓이: 250
c1 카드의 폭: 50, c1 카드의 높이: 80
c2 카드의 폭: 50, c2 카드의 높이: 80
*/
클래스이름.클래스변수
의 형태로 하는 것이 좋다.인스턴스변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 갖는다.
'메서드'는 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것이다.
기본적으로 수학의 함수와 유사하며, 메서드의 내부 과정은 몰라도 되고, 메서드에 넣을 값과 반환 결과만 알면 된다.
한 번 만들어 놓은 메서드는 몇 번이고 호출할 수 있으며, 다른 프로그램에서도 사용 가능하다.
반복되는 문장들을 메서드로 만들어서 사용하면 코드의 중복이 제거되고, 변경 사항이 발생했을 때, 이 메서드만 수정하면 되므로 관리도 쉽고 오류의 발생 가능성도 낮아진다.
public static void main(String args[]){
int[] numArr = new int[10];
// 프로그램의 전체 흐름이 한눈에 들어오도록
initArr(numArr); // 1. 배열을 초기화
printArr(numArr); // 2. 배열을 출력
sortArr(numArr); // 3. 배열을 정렬
printArr(numArr); // 4. 배열을 출력
public static void main(String args[]){
// 구조를 먼저 잡아 메서드를 작업단위로 만들어 놓고
switch(showMenu()) {
case1: inputRecord(); break;
case2: changeRecord(); break;
case3: deleteRecord(); break;
case4: searchRecord(); break;
default: showRecordList();
// showMenu(), inputRecord(), ... ,showRecordList() 까지 하나씩 구현해 나가기
int(=반환타입) add(=메서드이름) (int x, int y)(=타입 변수명, 타입 변수명, ...) { // 선언부
// 구현부: 메서드 호출시 수행될 코드
int result = a + b;
return result; // return 문: 반환타입과 일치하거나 자동형변환이 가능한 것이여야 함
}
(int x, int y)
같은 클래스 내의 메서드끼리는 참조변수를 사용하지 않고도 호출이 가능하지만, static메서드는 같은 클래스 내의 인스턴스 메서드를 호출할 수 없다.
class MyMathTest {
public static void main(String args[]){
// MyMath 클래스의 메서드를 호출하기 위해서 MyMath 클래스의 인스턴스를 생성한다.
MyMath mm = new MyMath();
long result1 = mm.add(5L, 3L);
double result2 = mm.divide(5L, 3L);
System.out.println("add(5L,3L):" + result1);
System.out.println("divide(5L,3L):" + result2);
}
}
class MyMath {
long add(long a, long b) { return a + b;}
// a, b가 5L, 3L인 long형의 값으로 호출이 가능한 이유
// long형인 5L가 double형인 5.0으로 자동 형변환되어 a, b에 저장되므로 연산결과가 double형이 된다.
double divide(double a, double b) { return a / b; }
}
메서드의 구현부를 작성할 때, 제일 먼저 해야 하는 일이 매개변수의 값이 적절한 것인지 확인하는 것이다. 가능한 모든 경우의 수에 대해 고민하고 그에 대비한 코드를 작성해야 한다.
float divide(int x, int y) {
// 작업을 하기 전에 y가 0인지 확인한다.
if (y == 0) {
return 0; // 매개변수가 유효하지 않으므로 메서드를 종료한다.
}
return x / (float) y;
클래스가 사용되면, 클래스에 대한 정보를 이 곳에 저장한다. 이 때, 그 클래스의 클래스 변수도 이 영역에 함께 생성된다.
인스턴스가 생성되는 공간이다.
메서드의 작업에 필요한 메모리 공간을 제공한다. 이 메모리는 메서드가 작업을 수행하는 동안 지역변수들과 연산의 중간결과 등을 저장하는데 사용되고, 작업을 마치면 할당되었던 메모리 공간은 반환되어 비워진다.
class Data { int x; }
class PrimitivieParamEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
Syste.out.println("x = + d.x); // 실행결과: x = 10
change(d.x);
System.out.println("x = " + d.x); // 실행결과: x = 10
}
static void change(int x) { // 기본형 매개변수
x = 1000;
System.out.println("x = " + d.x); // 실행결과: x = 1000
}
}
class Data { int x; }
class ReferenceParamEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("x = " + d.x);
change(d);
System.out.println("x = " + d);
}
static void change(Data d) {
x = 1000;
System.out.println("x = " + d.x);
}
}
반환 타입이 '참조형'이라는 것은 메서드가 '객체의 주소'를 반환한다는 것을 의미한다.
class Data { int x; }
class ReferenceReturnEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
Data d2 = copy(d);
System.out.println("d.x=" + d.x);
System.out.println("d2.x=" + d2.x);
}
static Data copy(Data d) { // 반환 값: Data 객체의 주소
Data tmp = new Data();
tmp.x = d.x;
return tmp;
}
}
메서드의 내부에서 메서드 자신을 다시 호출하는 것을 '재귀호출'이라 하고, 제귀호출을 하는 메서드를 '재귀 메서드'라 한다.
class FactorialTest {
static long factorial(int n) {
if (n <= 0 || n > 20) return -1; // 매개변수의 유효성 검사
if (n ==1) return 1;
return n * factorial(n-1);
}
}
인스턴스 메서드는 인스턴스 변수와 관련된 작업을 하는, 즉 메서드의 작업을 수행하는데 인스턴스 변수를 필요로 하는 메서드이다.
클래스 메서드는 메서드 중에서 인스턴스와 관계없는 메서드로 정의한다.
class MyMath2 {
long a, b; // 인스턴스 변수
// 인스턴스변수만을 이용해서 작업하므로 매개변수가 필요없다.
long add() { return a + b; }
// 인스턴스변수와 관계없이 매개변수로만 작업한다.
static long add(long a, long b) { return a + b; }
}
class MyMathTest2 {
public static void main(String args[]) {
// 클래스메서드 호출: 인스턴스 생성없이 호출 가능
System.out.println(MyMath2.add(200L, 100L));
// 인스턴스메서드 호출을 위한 인스턴스 생성
MyMath2 mm = new MyMath2();
mm.a = 200L;
mm.b = 100L;
// 인스턴스메서드는 객체 생성 후에만 호출이 가능
System.out.println(mm.add());
}
}
class MemberCall {
int iv = 10;
static int cv = 20;
int iv2 = cv; // 인스턴스 변수는 클래스 변수 사용 가능
static int cv2 = new MemberCall().iv // 클래스 변수는 객체를 생성해야 인스턴스 변수 사용 가능
// 클래스 메서드
static void staticMethod1() {
System.out.println(cv); // 클래스 변수 사용 가능
MemberCall c = new MemberCall(); // 객체를 생성해야 인스턴스 변수 참조 가능
System.out.println(c.iv);
}
// 인스턴스 메서드
void instanaceMethod1() { // 모두 바로 호출 가능
System.out.println(cv);
System.out.println(iv);
}
// 클래스 메서드
static void staticMethod2() {
staticMethod1();
MemberCall c = new MemberCall(); // 객체를 생성해야 인스턴스 메서드 호출 가능
c.instanceMethod1();
}
// 인스턴스 메서드
void instanceMethod2() { // 모두 바로 호출 가능
staticMethod1();
instanceMethod1();
}
}