변수의 선언위치에따라 변수의 종류가 나뉘어진다.
즉, 변수가 어디에 선언되었는가에 따라 변수의 종류와 범위(scope)가 결정되는 것이다.
범위 : 변수가 유효한 범위(변수를 사용할 수 있는 범위)를 말한다.
변수의 선언위치에 따라 결정되는 변수의 종류는 클래스변수, 인스턴스변수, 지역변수다.
class Variables{
// 인스턴스 변수
int instanceVariable;
// 클래스변수(static 변수, 공유가능한 변수)
static int staticVariable;
// 메서드(method)
puvlic void method{
// 메서드 영역(method Area)
// 지역 변수(local Variable)
int localVariable = 0;
}
}
클래스의 구성요소(멤버)라서 멤버변수라고 부른다.
같은 클래스의 모든 인스턴스들이 공유하는 변수다.
클래스가 메모리에 올라갈 때 자동으로 생성되기 때문에,
인스턴스 변수와 다르게, 인스턴스를 생성하지 않고 바로 사용이 가능하다.
클래스 변수를 선언하는 방법 : stiatc + 인스턴스변수
클래스 변수 접근 방법 : 클래스이름.클래스변수명
클래스 구성요소(멤버)리서 멤버변수라고 부른다.
인스턴스를 생성할 때 만들어지기 때문에 인스턴스 변수의 값을 읽어 오거나
저장하려면 먼저 인스턴스를 생성해야 한다.
각 인스턴스의 개별적인 저장공간을 가지고 있어서 인스턴스마다 다른 값을 저장할 수 있다.
인스턴스 변수 접근 방법 : 참조변수명.인스턴스 변수명
인스턴스를 생성할 때 인스턴스 변수가 생성되고, 인스턴스를 참조하는 참조변수가 없을 때
가비지 컬렉터에 의해서 자동으로 제거된다.
메서드 영역에서 선언되며, 메서드가 종료되면 지역변수도 소멸한다.
지역변수에는 static을 붙일 수 없다.
인스턴스변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있다.
클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로 항상 공통된 값만을 갖는다.
Class Car{
// 자동차 브랜드 명(회사명) : 클래스 변수
static String brandName = JavaCar;
// 자동차 이름, 색상, 가격 : 인스턴스 변수
String name, color, price;
}
자동차 클래스를 분석해보면 자동차 클래스에 정의될 수 있는 속성에는
브랜드 이름, 차 이름, 색상, 가격 등의 속성이 있을 수 있다.
이 중에서 차 이름, 색상, 가격은 자동차 종류마다 가져야 하는 고유의 값이지만
브랜드 명은 모든 자동차가 가져야하는 공통적인 속성이기 때문에
자동차 이름, 색상, 가격은 인스턴스변수로 선언하고 브랜드명은 static을 붙여서 클래스변수로 선언해야 한다.
-> 하나의 자동차 회사(브랜드)에서 생산되는 자동차들의 브랜드명이 각각 달라져서는 안되기 때문이다.
// System.out.println("Brand : " + Car.brandName);
System.out.println("Brand : " + car01.brandName);
작업을 수행하기 위한 명령문들을 묶어 놓은 것
메서드는 함수, function과 같은 의미인데 객체지향언어에서는 보통 메서드라고 부른다.
메서드는 일반적으로 어떤 값을 입력받아서 작업하고 그 결과를 돌려준다.
반복적인 코드를 줄이고 코드의 관리가 용이하다.
하나의 메서드가 하나의 작업을 수행하도록 작성하는 것이 재사용하기에 좋다.
여러 번 반복해서 사용되지 않는 코드라도 주요 작업단위로 묶어서
메서드로 만들어 놓으면 프로그램의 전체적인 흐름이 간결하게 정리된다.
메서드는 클래스 영역에서만 정의할 수 있다.
메서드 내에서는 또다른 메서드를 정의할 수 없다.
메서드를 정의하는 방법인데요. 메서드는 클래스 영역에만 정의할 수 있고요. 메서드 내에 메서드를 정의할 수 없다.
메서드는 크게 선언부와 구현부 두 부분으로 나뉜다.
선언부 : 메서드의 이름과 리턴타입 매개변수를 정의하는 곳
구현부 : 메서드가 호출되었을 때 실제로 수행되는 코드를 적는 곳
int add(int num1, int num2){
int result = num1 + num2;
// 호출한 메서드로 결과를 반환한다.
return result;
}
// 반환값이 없는 경우 리턴타입 대신 void를 사용한다.
public void speedUp(){
speed++;
}
add메서드는 두 개의 값을 받아서 더한 다음 그 결과를 반환하는 메서드다.
add메서드를 호출할 때, 두 개의 값 num1와 num2를 입력받아서 더한 결과를
변수 result에 담아서 반환한다.
return문은 메서드의 수행결과를 호출한 곳으로 반환한다.
add메서드에 사용된 변수 num1, num2, result는 선언된 곳이 모두
메서드 내에서 선언되었으므로 모두 지역변수이고 메서드가 종료되면 자동으로 소멸한다.
메서드 이름앞에 int는 반환하는 값의 타입을 적어주는 것이다.
만일 반환값이 없을 때는 speedUp메서드처럼 void라고 적어주면 된다.
-> void는 '비어있다’는 의미로 반환값이 없음을 뜻한다.
메서드의 문장들을 수행하고 더이상 수행할 코드가 없는 경우
수행중에 return문을 만났을 경우
return문을 만났을 경우return;
return 반환값;
int max(int a, int b){
// a > b면
if(a > b){
// a값 반환
return a;
// b가 a보다 크면
}else{
// b값 반환
return b;
}
}
int max(int a, int b){
int result = 0;
// a가 b보다 크면
if(a > b){
// result = a;
result = a;
// b가 a보다 크면
}else{
// result = b;
result = b;
}
// result값 반횐
return result;
}
참조변수.메서드 이름(); : 메서드에 선언된 매개변수가 없는 경우
참조변수.메서드 이름(값1, 값2...); : 메서드에 선언된 매개변수가 있는 경우
public class Math {
public int add(int a, int b) {
int result = a + b;
return result;
}
public static void main(String[] args) {
Math math = new Math();
int value = math.add(1, 2);
}
}
add메서드가 정의되어 있을 때 이 메서드를 호출하기 위해서는
먼저 add메서드가 정의되어 있는 Math클래스의 인스턴스를 생성한 다음에
참조변수(math)를 통해 add메서드를 호출하면 된다.
add메서드는 입력값으로 int타입의 변수a, b를 선언했으므로
호출할 때는 두 개의 int타입의 값을 제공해야한다.(math.add(1, 2))
호출할 때 제공된 값은 메서드의 매개변수a, b에 복사되고
이 값들을 이용해서 작업을 한다.public int add(int a(1), int b(2))
작업이 끝나면 결과값인 result가 메서드를 호출한 곳으로 반환되어
변수 value에 저장된다.(int value = 3)
이처럼 결과값이 있는 메서드를 호출하는 경우에는
메서드를 호출한 결과를 저장할 변수가 필요하다.
-> 메서드만 호출해서는 아무런 결과도 얻을 수 없다.
결과값을 저장할 변수 value 역시 add메서드의 리턴타입인 int로 지정해야 한다.
여기서 add메서드를 호출할 때 입력값으로 1과 2를 지정했으니까
1과 2는 각각 변수 a와 b에 저장된다.
변수 result에는 a + b의 결과인 3이 저장된다.
그 다음 return문에 의해서 result에 저장된 값 3이 호출한 곳으로 반환되어
변수 value에 add메서드의 호출결과인 3이 저장된다.
기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다.(read & write)
println메서드 호출(호출내용 : After change(d))
println메서드 호출(호출내용 : main() x : 1000)
main메서드에서 더이상 수행할 문장이 없으므로 main메서드 호출스택에서 제거, 프로그램 종료
대표적인 메서드 : main메서드
인스턴스 생성없이 클래스이름.메서드이름()으로 호출 가능하다.
인스턴스 변수(객체변수)나 인스턴스메서드와 관련없는 작업을 하는 메서드다.
메서드 내에서 인스턴스 변수를 사용할 수 없다.
메서드 내에서 인스턴스변수를 사용하지 않는다면 static을 붙이는
것을 고려한다.
인스턴스 생성 후 참조변수.메서드이름()으로 호출
인스턴스 변수나 인스턴스 메서드와 관련된 작업을 하는 메서드
메서드 내에서 인스턴스 변수 사용 가능
public class MyMath {
long a, b;
// 인스턴스 메서드
public long add() {
return a + b;
}
// 클래스(스태틱) 메서드
static long add(long a, long b) {
return a + b;
}
}
public class MyMathTest {
public static void main(String[] args) {
// 클래스 메서드 호출
System.out.println(MyMath.add(200L, 300L));
// 인스턴스 생성
MyMath mm = new MyMath();
mm.a = 100L;
mm.b = 400L;
// 인스턴스 메서드 호출
System.out.println(mm.add());
}
}
// result
500
500
MyMath클래스에 두개의 add메서드가 각각
인스턴스메서드이고, 클래스메서드로 정의되어 있다.
인스턴스메서드는 인스턴스변수 a와 b를 더하는 작업을 하기 때문에
별도의 입력값이 필요하지 않다.
클래스메서드는 인스턴스변수를 사용하는 대신
입력받은 두개의 값을 더해서 반환하는 작업을 한다.
인스턴스 메서드와는 달리 클래스메서드에서는
인스턴스변수 a, b를 사용하지 않았기에 static을 붙일 수 있었다.
MyMathTest클래스에서 메서드들을 각각 호출했다.
클래스메서드는 인스턴스를 생성하지 않고도 바로 호출이 가능하다.
인스턴스메서드는 먼저 인스턴스를 생성하고
인스턴스변수 a와 b에 각각 값을 저장하고 인스턴스메서드를 호출한다.
인스턴스 메서드는 인스턴스변수 a와 b의 합을 결과로 주게 된다.
같은 클래스의 멤버간에는 객체생성이나 참조변수 없이 참조할 수 있다.
그러나 static멤버들은 인스턴스 멤버들을 참조할 수 없다.
public class MethodCallTest {
// 인스턴스 메서드
public void instanceMethod() {}
// static메서드
static void staticMethod() {}
// 인스턴스 메서드
public void instanceMethod2() {
// 다른 인스턴스 메서드 호출 가능
instanceMethod();
// static메서드 호출 가능
staticMethod();
}
// static메서드
static void staticMethod2(){
// Error발생 : 스태틱 메서드에서는 인스턴스 메서드 호출 불가능
// instanceMethod();
// 다른 static메서드 호출 가능
staticMethod();
}
}
하나의 클래스에 정의된 멤버들은 서로 관련이 깊기 때문에
클래스 내에서는 이름만으로도 접근, 호출이 가능하다.
static멤버들은 인스턴스멤버를 이름만으로 접근, 호출이 불가능하다.
클래스멤버들은 인스턴스를 생성하지 않고도 사용할 수 있기 때문에
인스턴스를 생성해야만 사용할 수 있는 인스턴스멤버들을 사용하지 못하게 되어 있기 때문이다.
같은 클래스 내의 멤버들끼리는 서로 객체생성이나 참조변수 없이 참조할 수 있지만 static멤버들은 인스턴스멤버들을 참조할 수 없다.
public class VariableTest {
// 인스턴스 변수
int iv;
// 클래스(static)변수
static int cv;
// 인스턴스 메서드
public void instanceMethod() {
// 인스턴스 변수 사용 가능
System.out.println(iv);
// 클래스변수 사용 가능
System.out.println(VariableTest.cv);
}
// 클래스 메서드
static void staticMethod() {
// Error : 클래스메서드에서 인스턴스 변수 사용 불가
// System.out.println(iv);
// 클래스메서드에서 클래스변수 사용 가능
System.out.println(cv);
}
}
인스턴스메서드 instanceMethod()에서는 iv와 cv를 모두 사용할 수 있다.
클래스메서드인 staticMethod()는 인스턴스변수인 iv를 사용할 수 없다.