본문 바로가기
JAVA

[JAVA] 메소드

by 주옹스 2020. 8. 3.

메소드(Method) 란 ?

객체가 수행할 수 있는 연산 또는 행위를 기술한 것

 

 

 

[ 형식 ]

 

메소드 형식

 

 

 

 

 

[ 메소드 구성 ]

메소드 구성형식

 

 

 

 

 

[ 메소드 구성 형식 ]

1. 메소드 접근 제어자

- private : 클래스의 내부에서만 접근 가능하며 외부에서는 접근 불가

- default(생략) : 동일한 패키지(폴더)에 있는 클래스에서만 접근 가능

- protected : 동일한 패키지(폴더)에 있는 클래스 및 서브클래스에서 접근 가능

- public : 제약 없이 어디서나 접근 가능

 

 

2. 메소드 리턴 타입

    메소드에서 처리된 결과를 호출한 곳으로 되돌려 줄 때의 데이터 형을 의미 

    -> 메소드에서 처리된 결과를 호출한 곳으로 되돌려 줄 데이터가 없을 때, void형 사용

  

 

3. 메소드 이름

    메소드 이름은 일반적으로 소문자로 시작

 

 

4. 메소드 파라미터 (가인수) --> 메소드에서 받는 매개변수

    ㄱ. 메소드를 호출한 곳에서 메소드에 값을 전달할 때 사용

    ㄴ. 지역변수로 메소드 내에서만 유효한 범위를 갖는다.

 

 

5. 메소드 코드

    실제 메소드 구현 내용

 

 

6. 지역 변수

    ㄱ. 선언한 메소드 내에서만 사용 가능

    ㄴ. 메소드를 호출 할 때, stack 메모리 영역에 메모리를 할당 받으며 메소드를 빠져 나가면

         메모리가 해제

    

 

7. 메소드 리턴 값

    ㄱ. 호출한 곳으로 리턴값을 넘기면서, 호출한 쪽으로 제어가 넘어감

    ㄴ. return 되는 값은 메소드 리턴 타입과 동일한 자료형 이거나 작아야 한다.

    ㄷ. 메소드 리턴 타입이 void 형인 경우 "return;" 과 같이 기술하거나 생략할 수 있다.

 

 

 

리턴 타입이 void가 아닌 경우

 

리턴 타입이 void인 경우

 

 

 

- STACK 이란 ? 

   - 스택은 자료의 삽입과 삭제가 한쪽 끝에서만 수행되는 선형 구조

   - LIFO( Last In First Out ) 구조

   - push : 스택에 데이터를 삽입하는 것

   - pop : 스택에서 데이터를 삭제하는 것

   - top : 스텍의 가장 위 데이터를 가리키는 위치

STACK 이미지

 

 

- 메모리의 STACK 영역

 

   ㄱ. 메소드 호출과 관계되는 지역 변수와 매개 변수를 저장하는 영역

   ㄴ. 스택 영역은 메소드 호출과 함께 할당 되며, 메소드의 호출이 완료 되면 소멸

   ㄷ. 스택 영역에 차례로 저장되는 메소드의 호출 정보를 스택 프레임(stack frame)이라 한다.

 

 

 

- JAVA STACK영역

   ㄱ. 자바 스택은 각 스레드가 생성됨과 동시에 생성되며, 각 스레드 별 서로 독립적으로 자바 스택을 유지

   ㄴ. 각 스레드를 위한 자바 스택에서는 현재 실행하고 있는 각 메소드를 위한 STACK Frame을 포함한다.

  

 

 

 

 

- 메소드 종류

  1. 인스턴스 메소드

 

       ㄱ. 객체를 생성 후에 객체를 이용하여 접근 할 수 있는 메소드

       ㄴ. 메소드 내에서 인스턴스 변수나 클래스 변수를 바로 접근하여 사용 할  수 있다

       ㄷ. 메소드 내에서 다른 인스턴스 메소드클래스 메소드를 호출 할 수 있다.

 

  

 

  2. 클래스 메소드

      ㄱ. 메소드의 리턴 타입 앞에 static키워드를 붙여서 선언

      ㄴ. 객체 생성과 무관하게 클래스 이름을 이용하여 바로 호출할 수 있는 메소드

      ㄷ. 클래스 변수는 바로 접근하여 사용할 수 있다.

      ㄹ. 객체가 생성 되지 않아도 호출 할 수 있으므로 메소드 내에서 인스턴스 변수나 인스턴스 메소드를

           바로 접근하여 사용할 수 없다.

      ㅁ. 클래스 메소드 내에서 인스턴스 변수나 인스턴스 메소드를 접근하기 위해서는 먼저 객체를

           생성하고 생성된 객체를 통해서만 접근 가능하다.

      ㅂ. 클래스 메소드 내에는 this나 super키워드를 사용할 수 없다.

      ㅅ. 클래스 메소드는 자동으로 final메소드가 되어 overriding이 불가능 하다.

 

 

인스턴스 메소드와 클래스 메소드 예제

 

 

 

 

 

      

        *  public static void main(String[] args) ?

 

           static이 없으면 객체를 생성해야만 main을 접근할 수 있지만 JVM은 객체를 자동으로 생성하지는 않으므로 

           main을 클래스로 선언하지 않으면 main함수가 실행이 되지 않는다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package ex0803;
 
public class MethodSort {
    
    //인스턴스변수는 객체를 생성해야 사용
    int a = 10, b = 20//필드. 인스턴스 변수
    //클래스변수는 객체를 생성과 상관없이 사용
    static int x = 100//필드. 클래스 변수
    
    public void sub1() { //인스턴스메소드
        sub2(); //sub1도 인스턴스이기 때문에 sub2를 그냥 부를 수 있음
        System.out.println(a+":"+b);
        System.out.println(x); //객체를 생성하던 생성하지 않던 상관 없는 클래스 멤버이기 때문에 
    }
    
    //인스턴스메소드는 객체를 생성해야 호출 할수 있는 메소드
    public void sub2() { //인스턴스메소드
        System.out.println("sub2...");
        
    }
    
    //클래스메소드는 객체 생성과 상관 없이 호출
    public static void sub3() { //클래스메소드
        
        //System.out.println(a); //컴파일오류
        //sub1(); //컴파일오류 
        System.out.println(x);
        
        MethodSort ob = new MethodSort();
        ob.sub1(); //인스턴스 메소드이기 때문에 객체생성해야함
    }
    
    public static void main(String[] args) { //클래스메소드
    
        // sub1(); //컴파일 오류 -> main은 클래스 메소드이기 때문에 객체 생성해줘야함
        //System.out.println(a); //컴파일오류
        
        System.out.println(x);
        
        sub3();
    }
}
 
class User3 {
    public void method1() {
        
        //System.out.println(x); //오류 다른 클래스에서 부르기 때문에 Ex3.x로 써야함
        System.out.println(MethodSort.x);
        
        
        //System.out.println(MethodSort.a); //오류 다른 클래스에서 부르기 때문에 Ex3.x로 써야함
        //System.out.println(MethodSort.a); //컴파일오류 -> 객체생성해야함
        
        MethodSort e = new MethodSort();
        System.out.println(e.a);
    }
    
    
    public static void method2() {
        
        MethodSort.sub3(); //클래스 메소드 --> 같은 클래스 안에서는 그냥 sub3()으로만 호출 가능 
                           //              다른 클래스에서 클래스메소드 호출하고 싶을 때, 클래스이름.sub3()으로 호출
        
    }
}
 
 
cs

 

 

 

 

- 메소드의 인수 전달

 

   1. Call By Value (값에 의한 호출)

    - 기본 자료 형으로 인수를 전달

    - 값을 호출된 메소드의 인수에 복사하며 복사된 값은 메소드 내에서 local value특징을 갖는다.

    - 호출 메소드와 호출된 메소드가 각각의 매개 변수에 대한 기억 공간을 따로 확보하여 각각

      독립적으로 사용

    - 메소드의 형식 매개변수 값이 변경되어도 호출한 메소드의 실 매개변수 값은 변경되지 않는다.

 

call by value

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package ex0803;
 
public class CallByValue {
    public static void main(String[] args) {
        User4 u = new User4();
        int x = 5;
        // 매개변수 전달 기본자료형 : call by value
        // 실매개변수와 형식 매개변수가 기억공간 따로 확보
        u.sub(x); //x:실매개변수
        System.out.println(x); //5
    }
}
 
 
class User4{
    public void sub(int a) { //a: 형식 매개변수
        a+=10;
        System.out.println("sub:"+a); //15
    }
}
cs

 

 

 

 

2. Call By Reference (참조에 의한 호출)

   - 레퍼런스 형으로 인수를 전달 (배열, 클래스 참조형, 인스턴스 참조형 등)

   - 호출된 메소드로 값(value)를 전달 하는 것이 아니라 참조 위치를 전달(=주소값)한다.

 

 

 

    1) 객체 Call By Reference

 

객체 Call By Reference

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package ex0803;
 
public class Object_CallByReference {
    public static void main(String[] args) {
 
        User5 u = new User5(); //참조형변수 -> 주소만 저장!
        System.out.println(u.a); //10
            
        // call by reference : 참조변수를 매개변수로 전달
        // 실매개변수와 형식매개변수가 같은 기억공간을 참조
        
        
        u.sub(u); //객체를 매개변수로 전달 -> 주소값을 전달
        System.out.println(u.a); //60
    }
}
 
 
class User5{
    
    int a = 10//필드 (지역변수아님)
    
    public void sub(User5 ob) {//이 줄을 메소드 시그니처라 함 //main에서 주소값을 전달받음
        ob.a +=50;
        System.out.println("sub ob.a: "+ ob.a);
    }
}
cs

 

 

 

  2) 배열 Call By Reference

   

배열 Call By Reference

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package ex0803;
 
public class Array_CallByReference {
    public static void main(String[] args) {
        
        User6 ob = new User6();
        int[] n = {1,2,3,4,5};
        
        ob.sub(n); //배열은 참조형변수 -> 주소값을 넘김
                   //Call By Reference
        
        for(int i = 0; i<n.length; i++) {
            System.out.print(n[i]+" ");
        }
        System.out.println();
    }
}
 
 
class User6{
    public void sub(int[] num) {
        num[1]=100;
    }
}
cs

 

 

 

 

- 메소드 오버로딩(Method Overloading) 이란 ?

 

 

   1) 한 클래스 내에서 이름이 같은 메소드를 정의하는 것.

       

       ㄱ. 매개변수의 타입이 다르거나 매개변수의 개수가 달라야한다.

           -> 오버로딩 된 메소드는 매개변수에 의해서만 구분됨

 

       ㄴ. 매개변수는 같으나 반환형이 다를 경우 컴파일 오류가 발생한다.

            -> 메소드 리턴 타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.

 

 

 

    2) 메소드 시그니처 (Method Signature)

       

        ㄱ. 메소드 구분에 사용되는 메소드 이름, 파라미터 변수의 수, 타입, 순서를 묶어서 메소드 시그니처라고 부름

              ex) public int Score(int a)

   

 

   

    3) 처리하는 기능이 같은 메소드의 이름을 동일하게 부여하여 프로그램 가독성을 증가시킨다.

        -> 메소드 오버로딩의 예 System.out.println()

 

 

 

     4) 생성자도 중복 정의가 가능

 

   

 

Overloading

 

 

 

 

 

[ 배열의 객체생성 예제 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package ex0803;
 
import java.util.Scanner;
 
public class Score {
    private Scanner sc = new Scanner(System.in); //여기서는 close안해도 됨. JVM이 알아서 해줌
    
    private int cnt; //필드는 초기화 하지 않으면 0 //필드 -> 전역변수
    
    
    private ScoreVO []list = new ScoreVO[50]; //정보를 저장하는 주소를 저장하는 배열(필드) 
    //private ScoreVO v1,v2,v50; //10번줄과 11번줄 같음
    
    
    public void input() {
        
        if(cnt>=50) {
            System.out.println("데이터를 더이상 입력 할 수 없습니다...");
            return;
        }
        
        System.out.print("\n데이터 입력...");
        
        //<<오류!!!>>
        /*
        //java.lang.NullPointerException 오류 
        String s = sc.next();
        list[cnt].setName(s); //객체에 대한 메모리할당 받지 못함.--> 생성자 필요!
        */
        
        /*
        //java.lang.NullPointerException 오류
        String s = sc.next(); 
        ScoreVO vo = null; //객체 생성이안됨
        vo.setName(s);
        */
        
        
        /* 방법 1
        ScoreVO vo = new ScoreVO(); //vo:주소
 
        System.out.print("이름 ? ");
        vo.setName(sc.next());
        
        System.out.print("국어 ? ");
        vo.setKor(sc.nextInt());
        
        System.out.print("영어 ? ");
        vo.setEng(sc.nextInt());
        
        System.out.print("수학 ? ");
        vo.setMat(sc.nextInt());
        
        list[cnt]=vo; //vo객체를 생성해서 list에 담음
        */
        
        // 방법 2  --> new다음 클래스를 해야 객체가 생성!!!!
        list[cnt] =new ScoreVO(); //아예 처음부터 list에 ScoreVO객체를 담음
        
        System.out.print("이름 ? ");
        list[cnt].setName(sc.next());
        
        System.out.print("국어 ? ");
        list[cnt].setKor(sc.nextInt());
        
        System.out.print("영어 ? ");
        list[cnt].setEng(sc.nextInt());
        
        System.out.print("수학 ? ");
        list[cnt].setMat(sc.nextInt());
        
        cnt++;
    }
    
    
    public void print() {
        System.out.println("\n데이터 출력...");
        System.out.println("전체인원수 :" +cnt);
        
        for(int i = 0; i<cnt; i++)
        {
            System.out.print(list[i].getName()+"\t");
            System.out.print(list[i].getKor()+"\t");
            System.out.print(list[i].getEng()+"\t");
            System.out.print(list[i].getMat()+"\t");
            System.out.print(list[i].getTot()+"\t");
            System.out.print(list[i].getAvg()+"\n");
        }
    }
    
    public void search() {
        System.out.print("\n데이터 검색...");
    }
    
}
 
cs

 

 

 

 

[ 클래스에서 입.출력 메소드 작성 예제 ]

set,get 자동생성 -> ctrl + shift + s+r  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package ex0803;
 
/*
 * - 속성
 *   이름, 국, 영, 수 , 총, 평균
 *   => 최대 50명
 *   
 * - 기능
 * 1. 입력
 * 2. 출력
 * 3. 검색  
 *  
 * */
 
//VO ->value object :한사람의 자료를 저장하는 것.
 
public class ScoreVO {
    private String name;
    private int kor;
    private int eng;
    private int mat;
    
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getKor() {
        return kor;
    }
    public void setKor(int kor) {
        this.kor = kor;
    }
    public int getEng() {
        return eng;
    }
    public void setEng(int eng) {
        this.eng = eng;
    }
    public int getMat() {
        return mat;
    }
    public void setMat(int mat) {
        this.mat = mat;
    }
    
    
    //총점
    public int getTot() {
        return kor+eng+mat;
    }
    
    //평균
    public int getAvg() {
        return getTot()/3;
    }
    
    
}
 
cs

 

 

[여러 자료형의 메소드 작성 하기]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
package ex0803;
 
public class Practice_method1 {
    public static void main(String[] args) {
 
        // 객체 생성
        User1 u = new User1();
        // 생성자는 new다음에만 호출가능
        // 생성자는 객체 생성할때에만 호출한다
        // 생성자안에서는 필드를 초기화하는 코드를 기술한다
 
        int a;
        // a=u.sum(10);
        // System.out.println(a);
 
        // a = u.sum2(10, 1);
        // System.out.println(a);
 
         a = u.odd(10);
         System.out.println(a);
 
        System.out.println(u.isUpper('a')); // false
        System.out.println(u.isUpper('D')); // true
        System.out.println();
 
        System.out.println(u.lower('D'));
        System.out.println();
        
        System.out.println(u.ascii('c'));
        System.out.println();
        
        System.out.println(u.ascii_to_char(65));
        System.out.println();
        
        // void메소드는 결과를 되돌려 받지 않는다.
        u.gugu(3);
        System.out.println();
        
        u.triangle(5);
        System.out.println();
        
        System.out.println(u.grade(101));
        System.out.println();
        
        int []ss = u.random(10);
        System.out.print("\n난수: ");
        for(int i = 0; i<ss.length; i++)
            System.out.print(ss[i]+" ");
        System.out.println();
        
        System.out.println(u.hak(86));
        System.out.println();
    }
}
 
//메소드 작성 연습!
class User1 { // class 시작 이름은 대문자
 
    public int sum(int n) { // 메소드 시작이름은 소문자
                            // n:매개변수(가인수 -> 받는 매개변수)
 
        int s = 0// 지역변수. 메소드를 호출할 때 메모리 할당을 받고, 메소드를 빠져나갈때 사라짐.
 
        for (int i = 1; i < n; i++) {
            s += i;
        }
 
        return s;
    }
 
    // 매개변수가 2개인 경우 : 동일한 자료형이라 할지라도 각각 자료형 기술
    public int sum2(int a, int b) { // 적은수에서 큰수까지의 합
        int s = 0;
 
        int temp;
        if (a > b) {
            temp = a;
            a = b;
            b = temp;
        }
 
        for (int i = a; i <= b; i++) {
            s += i;
        }
 
        return s;
    }
 
    // 1~n까지 홀수합 구하는 메소드 작성(odd)
    public int odd(int n) {
        int s = 0;
        for (int i = 1; i <= n; i += 2)
            s += i;
        return s;
    }
 
    // 어떤 문자가 대문자이면 true, 그렇지 않으면 false (isUpper)
    public boolean isUpper(char ch) {
 
        return ch >= 'A' && ch <= 'Z';
        // if(ch <= 'A' && ch>='Z') return true;
        // else return false;
    }
 
    // 어떤 문자가 대문자이면 소문자로 변환하고 그렇지 않으면 전달받은 문자를 그래도 반환 : lower
    public char lower(char ch) {
        return ch >= 'A' && ch <= 'Z' ? (char) (ch + 32) : ch;
    }
 
    // 한 문자를 인수로 넘겨받아 문자의 ascii코드 반환 (ascii)
    public int ascii(char ch) {
        return ch;
    }
 
    // ascii코드를 인수로 넘겨 받아 코드에 대한 문자반환
    public char ascii_to_char(int a) {
        return (char) a;
    }
 
    // 1~9사이의 숫자를 인수로 넘겨받아 해당하는 구구단을 출력
    // 단, 수가 1~9사이가 아니라면 아무것도 출력하지 않는다.
    public void gugu(int n) {
 
        if (n < 1 || n > 9)
            return// 메소드 리턴 타입이 void인 경우 생략가능
 
        for (int i = 1; i <= 9; i++) {
            System.out.printf("%d * %d = %d\n", i, n, (i * n));
 
        }
    }
 
    public void triangle(int n) {
        for(int i = 1; i<=n; i++) {
            for(int j = 1; j<=n-i; j++) {
                System.out.print(" ");
            }
            for(int j = 1; j<=i*2-1; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
    
        
   //점수에 따른 평점 (95~100 : 4.5, 90~94 : 4.0 , ..., 0~ 59 : 0 , 나머지 :-1)
        //grade (double형)
        
    public double grade(int s)
    {
        double a = -1;
        
        if(s < 0 || s>100return a;
        
        if(s>=95) a = 4.5;
        else if(s>=90) a = 4.0;
        else if (s >= 85) a = 3.5;
        else if(s >= 80)a = 3.0;
        else if(s >= 75) a = 2.5;
        else if(s >= 70) a = 2.0;
        else if(s >= 65) a = 1.5;
        else if(s >= 60) a = 1.0;
        else if(s>=0) a = 0;
        
        return a; //반환 하나
    }
    
    
    // 정수를 매개변수로 넘겨 받아 1~100 까지의 
    // 난수를 매개변수개수만큼 반환 --> **반환 개수가 여러개 일 때!!!!!** --> 배열!!!
    public int[] random(int n) {
        int [] nn = null//메모리 할당해야함
 
        nn = new int[n];
        
        for(int i = 0; i<n; i++)
            nn[i] = (int)(Math.random()*100)+1;
        
        return nn; //배열을 리턴!!! --> 배열의 주소를 리턴시킴
    }
    
    
    //점수에 따른 학점 
    //95~100 : A+ , 90~94 : A, .....0~59 : F
    public String hak (int n) {
        
        String h = null;
        
        if(n>= 95 && n<=100) h="A+";
        else if(n>= 90 && n<95)h="A";
        else if(n>= 85 && n<90)h="B+";
        else if(n>= 80 && n<85)h="B";
        else if(n>=75 && n<80)h="C+";
        else if(n>=70 && n<75)h="C";
        else if(n>=65 && n<70)h="D+";
        else if(n>=65 && n<60)h="D";
        else if(n<60) h="F";        
 
        return h;
    }
    
}
 
cs

 

 

 

'JAVA' 카테고리의 다른 글

[JAVA] 비정형인자  (0) 2020.08.04
[JAVA] 재귀 호출  (0) 2020.08.04
[JAVA] 레퍼런스 변수  (0) 2020.08.03
[JAVA] 클래스  (0) 2020.07.31
[JAVA] 객체지향  (0) 2020.07.31