static 메서드와 인스턴스 메서드

메서드 앞에 static이 붙으면 static 메서드라 함 (클래스 메서드라고도 함)

static이 안 붙으면 인스턴스 메서드라 함

두 메서드를 구별하는 기능적인 차이는 인스턴스 멤버의 사용 여부이다. 

 

인스턴스 메서드

인스턴스 생성 후 '참조변수.메서드 이름()'으로 호출함

인스턴스 변수(iv), 인스턴스 멤버(im)와 관련된 작업을 함

메서드 내에서 iv 사용 가능

 

static 메서드

객체 생성 X

'클래스 이름.메서드 이름()'으로 호출함

인스턴스 변수(iv), 인스턴스 멤버(im)와 관련되지 않은 작업을 함

메서드 내에서 iv 사용 불가능

 

 

예시1

class mymath{
	long a,b; //인스턴스 변수
    
    long add(){	//인스턴스 메서드
    	return a+b;
    }
    
    static long add(long a, long b){ 	//클래스 메서드(static 메서드)
    	return a+b; //지역변수 a,b
    }   
}

static메서드와 인스턴스 메서드 호출은 다음과 같다. 

class example{
	public static void main(Stringp[] args){
    
    	System.out.println(mymath.add(200L,100L); //클래스(static)메서드 호출
 
 
    	mymath mm = new mymath();	//인스턴스 생성
        mm.a = 200L;
        mm.b = 100L;
        System.out.println(mm.add()); // 인스턴스 메서드 호출
   }
}

 

예시2

class Test{
	int iv;	//인스턴스 변수
   	 static int cv; //클래스 변수
    
    void instanceMethod1(){}
    static void staticMethod1(){}
    
    void instanceMethod(){
    	System.out.println(iv);
        System.out.println(cv);
        //iv,cv 모두 사용 가능
        
        instanceMethod1();
        staticMethod1();
        //인스턴스 메서드와 static메서드 모두 호출 가능
    }
    
    static void staticMethod(){
    	//System.out.println(iv);	//iv 사용 불가능!!
        System.out.println(cv);
        
       //instanceMethod1();			//인스턴스 메서드 호출 불가능!!
        staticMethod1();
        
    }
    
}

즉!! static 메서드는 인스턴스 변수와 인스턴스 메서드 모두 호출 불가능!! 나머지는 가능

 

 

메서드의 매개변수 

메서드의 매개변수 타입은 기본형, 참조형으로 나눌 수 있음

 

기본형 매개변수

변수의 값을 읽기만 하고 변경은 불가능함

class Data{
	int x;
}

class example{
	public static void main(String[] args){
    	Data d = new Data();	//객체 생성
        d.x = 10;
        System.out.println(" main() : x = "+ d.x);
        
        change(d.x);
        System.out.println(" main() : x = "+ d.x);
     }
     static void change(int x){		//기본형 매개변수
     	x = 1000;
        System.out.println("change() x : "+x);
}

"main() :  x = "에 대한 두개의 출력값은 모두 "10"이다. 

"change() x"는 1000이 출력된다. 

change( )호출이 되어서 x값을 1000으로 바꾸더라도 지역변수를 바꾼 것이기 때문에, 그대로 10만 출력되는 것

 

"기본형 매개변수"는 "읽기"만 가능함!!

 

참조형 매개변수

변수의 값을 읽고 변경 할 수 있음

class Data{
	int x;
}

class example{
	public static void main(String[] args){
    	Data d = new Data();	//객체 생성
        d.x = 10;
        System.out.println(" main() : x = "+ d.x);
        
        change(d);
        System.out.println(" main() : x = "+ d.x);
     }
     
     static void change(Data d){		//참조형 매개변수
     	d.x = 1000;
        System.out.println("change() x : "+d.x);
}

change() 이전 출력값은 10이고, change( ) 이후 출력되는 모든 값이 "1000"이다. 

change( )의 매개변수가 type이 기본형이 아니기 때문에 참조형 매개변수~! 

 

 main( )이 change( )에 객체 d에 대한 "리모콘"을 줬다고 생각하면 조금.. 쉽다!

 

참조형 반환타입

class Data{
	int x;
}

class example{
	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 tmp = new Data(); //새로운 객체 tmp 생성
        
        tmp.x = d.x //d.x의 값을 tmp.x에 복사
        
        return tmp;	//복사한 객체의 주소 반환
     }
}

출력값은 d.x와 d2.x 모두 10이다.

 

stack이란? 

밑이 막히고 위가 뚫린 상자라고 생각하면 된다. 위에 차곡 차곡 쌓인다. 

따라서 꺼낼때는 제일 위에있는 것부터 차례로 꺼낸다. 

★ 중간에 끼워 넣거나 아래 있는 것을 빼낼 수 없다

 

call stack이란?

메서드 수행에 필요한 메모리가 제공된 공간으로,

메서드가 호출되면 호출 스택에 메모리를 할당하고 종료 시 해제 한다. 

 

예시로 설명하자면.. 

1. 호출 스택에 main( )이 있음

2. main()이 println()을 호출

3. 호출 스택에 아래서부터 차례로 main( ) , println( )이 쌓여 있음

 이때, main( )은 대기상태, println( )은 실행상태 

4. println( )이 종료

5. 호출스택에 main( )만 남음

 

따라서.. 

→ 아래에 있는 메서드가 위에 있는 메서드를 호출한 것

→ 하나의 스택에서는 한개의 메서드만 실행, 나머지는 대기 상태

 

코드 분석 시, 단계별로 호출 스택을 직접 그려보면 프로그램의 실행과정을 정확히 이해할 수 있음!

 

 

메서드란?

메서드란?

코드의 중복을 제거하기 위해서 { 해당 문자들 }을 묶은 것으로, 값을 입력받아 결과를 출력(반환)한다. 

 

※ 메서드 vs 함수

더보기

메서드는 클래스 안에 들어있어야 하는 것

함수는 클래스에 독립적임

 

메서드의 장점?

- 중복 코드 제거

- 관리 용이

- 재사용 가능 

 

참고로, 하나의 메서드하나의 기능만 수행하도록 작성해야 함

 

메서드 = 선언부 + 구현부

반환타입 메서드이름 (타입 변수명, 타입변수명, ...) // 선언부
{												// 구현부
	//코드			  							// 구현부
}												// 구현부
int add(int x,int y){
	int res = x+y;
    return res;
}

 

메서드 호출

메서드 이름(값1, 값2, ...);

위의 형식과 같이 메서드를 호출하는데, return type에 따라 작업 결과를 저장해야 할 경우는 주의해야 함!

 

→ 예시코드

public static void main(String[] args){
	MyMath mm = new MyMath();
    
    //add 메서드 호출
    long res1 = mm.add(5L,3L);
    double res2 = mm.add(5L,3L);
    
    System.out.println("res1 : "+ res1);
    System.out.println("res2 : "+res2);
}

class MyMath{
	long add(long a, long b){
    	long res = a+b;
        return res;
   }
   
   long substract(long a, long b){ return a-b}
   
   //...
}

메서드는 클래스 영역에만 정의를 저장

 

메서드의 실행 흐름

1. 객체 생성(인스턴스 생성)

2. 메서드 호출- 메서드의 매개변수에 인수가 각각 대입됨

3. 메서드의 모든 문장이 끝나거나 return을 만나면 반환

 

return문

return문이란? 

실행 중인 메서드를 종료하고 호출한 곳으로 되돌아가도록 한다. 

return;
return a;

 

반환 타입이 void일 경우 생략 가능, 컴파일러가 자동 추가됨

반환 타입이 void가 아닐 경우, 반드시 return문 필요

 

참고로, 다음의 경우에 "return문이 없다"는 에러가 발생한다. 

int max(int a,int b){
	if(a>b) return a;
}

Why? 참일경우엔 a를 반환하지만, 거짓일 경우에 어떤 값을 반환해야하는지 없기 때문! 

 

반환값

말 그대로 return되는 값으로, void type이 아닐 때, return 옆에 쓰는 것

반환 type과 반환값의 type이 일치해야 함

 

선언 위치에 따른 변수의 종류

선언 위치에 따라 종류가 3가지로 나뉜다. 

(1) iv  인스턴스 변수 (2) cv 클래스 변수(static, 공유 변수) (3) lv(지역 변수)

 

코드로 구분해 보면 다음과 같다. 

class Variables{
    int iv;	//인스턴스 변수
    static int cv;	//클래스 변수 
    
    void method(){
    	int lv =0; //지역 변수
    }
}

 

(1) iv(instance variable)

인스턴스가 생성되었을 때 생성

Time class가 있다고 가정할 때, "int hour; int min; int sec;" 이것들을 iv라 할 수 있음! 

언제 생성됨? 객체를 생성할 때, 만들어짐

객체는 iv를 묶어놓은것! 이라고 이해하면 쉽다. (엄밀히 얘기하면 틀린 말이지만, 일차적인 이해를 위해서는 이렇게 생각하는 것이 좀 더 쉬울 것)

 

(2) cv(class variable)

클래스가 메모리에 올라갈 때 생성

클래스(설계도가)필요할 때 만들어짐 - 

 

(3) lv(local variable)

변수 선언문이 수행되었을 때 생성

 

영역은 크게 클래스 영역, 메소드 영역으로 나뉜다. 

클래스 영역에서 선언된 변수를 iv라 하고, static한 변수의 경우는 cv라 한다.

메소드 영역(클래스 영역 이외의 영역)에서 선언된 변수를 lv라 한다. 

 

클래스 영역에서 선언되는 변수는 인스턴스 변수와 클래스 변수가 있는데 이 둘의 차이는 무엇일까?

객체의 속성 중 개별적인 속성을 갖는 변수는 인스턴스 변수!

객체의 속성 중 공통적인 속성을 갖는 변수는 클래스 변수! static을 붙임

 

카드로 예시들면 조금 쉽다. 

class Card{

	//개별적인 속성
	String kind; //무늬
    int number; //숫자
    
    //공통적인 속성
    static int width = 100; //폭
    static int height = 250; //높이
}

 

해당 클래스를 사용하려면 다음과 같이 쓸 수 있다. 

Card c = new Card(); //객체 생성
//객체의 사용
c.kind = "HEART";	
c.number = 5;

Card.width =200;
Card.height=300;

클래스 변수를 사용할 때, 참조변수(c.width, c.height)로 써도 되지만, 권장하지 않음 

 

 

 

클래스의 정의

클래스의 정의는 크게 3가지로 나눌 수 있다. 

(1) 설계도 (2) 데이터 +함수 (3) 사용자 정의 타입

 

(1) 설계도

말그대로 설계도.. "https://bskwak.tistory.com/219" 참고 

 

)2) 클래스 == 데이터 + 함수

 

※ 배열 vs 구조체 

더보기

배열은 같은 type만 묶을 수 있고 

구조체는 다른 type도 묶을 수 있음

구조체에서 좀 더 발전(?)된 형태가 클래스라 할 수 있음

클래스 == 구조체(다양한 type 변수) + 함수(메서드) 

 

(3) 사용자 정의 타입

원하는 타입을 새로 만듦 - 예를 들면 시간 같은거? 

/*1*/
int hour;
int min;
int sec;

/*2*/
int hour1, hour2, hour3;
int min1, min2, min3;
int sec1, sec2, sec3;

/*3*/
int[] hour = new int[3]; 
int[] min = new int[3];
int[] sec = new int[3];

class 로 시간에 대한 "hour, minute, second"를 하나로 묶어서 코드를 써보면 다음과 같다. 

class Time{
	int hour;
    int minute;
    int second;
}

/*1*/
Time t = new Time();

/*2*/
Time t1 = new Time();
Time t2 = new Time();
Time t3 = new Time();

/*3*/
Time[] t = new Time[3];
t[0] = new Time();
t[1] = new Time();
t[2] = new Time();

코드가 훨~씬 간결해지고 시분초가 하나로 묶이기 때문에 이전 코드처럼 따로 분리되는 현상이 사라짐 

 

이전 코드 : 비 객체 지향 코드 

이후 코드 : 객체 지향적 코드 (관련된 값들을 묶을 수 있고 간결해짐)

하는 일의 차이는 없지만, JAVA와 같은 객체 지향 언어에서는 이후 코드가 적합

객체의 생성과 사용

1. 클래스 작성

설계도 작성이라 생각하면 쉽다. 

class Tv{
	//3개의 변수
	String color;
	boolean power;
    int channel;
    
    //3개의 매서드
    void power(){
    	power = !power;
    }
    void channelUp(){
    	channel++;
   	}
    void channelDown(){
    	channel--;
    }
}

위의 클래스는 변수 3개, 매서드 3개로, 총 6개의 멤버를 가지고 있다.

 

2. 객체의 생성

클래스명 변수명;  : 클래스의 객체를 참조하기 위한 참조 변수 선언
변수명 = new 클래스명(); : 클래스의 객체를 생성 후, 객체의 주소를 참조변수에 저장

Tv t; //Tv 클래스 타입의 참조변수 t 선언 
t = new Tv(); //Tv 인스턴스 생성 후, 생성된 Tv인스턴스의 주소를 t에 저장

다음과 같이 한줄로 줄일 수 있다. 

Tv t = new Tv();

 

 

3. 객체의 사용

객체가 가지고 있는 변수와 메소드를 사용한다는 뜻

t.channel = 7;	//변수 사용
t.channelDown(); //메서드 사용

 

4. main에서 사용 방법 

class Tvexample{
	public static void main(String[] args){
    		Tv t = new Tv();
        	t.channel = 7;
        	t.channelDown();
       	 	System.out.println("현재 채널은 "+ t.channel+" 입니다.");
    	}
}

 

5. 객체 배열

객체배열 == 참조변수 배열

아래 코드와 같이 객체 배열 생성과 각각 객체 생성하는 것은 다르다는 것 주의 

Tv[] tvArr = new Tv[3]; //객체 배열 생성

//객체 생성
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();

 

 

 

+ Recent posts