[JAVA] 자바 클래스 내부 구성 - 메서드

    728x90

    안녕하세요

    로로봉입니다. : )

    지난번에는 필드에 대해 알아보았습니다. 오늘은 클래스의 내부 구성 요소 중 두 번째인 메서드에 대해 알아보도록 하겠습니다.


    1) 메서드 정의

    메서드는 클래스의 기능에 해당하는 요소입니다.

    먼저 메서드 정의의 문법적 구조를 살펴보도록 하겠습니다.

    자바제어자 리턴(반환)타입 메서드명(입력매개변수) {
       메서드 내용
    }
    
    
    public static int sum(int a, int b) {
       // 메서드 내용
    }

    리턴 타입은 메서드 종료 이후 반환되는 값의 자료형을 의미합니다.

    메서드명은 변수명 선정 규칙과 동일하며, 보편적으로 소문자로 시작합니다.

    소괄호 안에는 입력 매개변수가 들어오는데, 메서드를 호출할 때 전달되는 값의 자료형과 전달받은 값을 저장할 지역 변수명을 정의합니다.

    마지막 중괄호 안에는 메서드의 내용이 들어가는데, 여기에 메서드가 수행해야 할 기능을 작성하면 됩니다.


    2) 여러 리턴 타입의 메서드

    여러 자료형이 있듯이 메서드를 호출하고 결과를 반환하는 자료형도 다양하게 사용할 수 있습니다.

    이러한 자료형을 리턴할 필요가 없을 때에는 void 형을 사용하면 반환하는 값이 없다는 것을 의미합니다.

    void print() {
       System.out.println("Hello");
    }
    
    int data() {
       return 3;
    }
    
    double sum(int a, double b) {
       return a + b;
    }

    print() 메서드를 보면 void형이기 때문에 return 코드가 들어가 있지 않습니다. void형에서 return; 을 사용하면 그 위치에서 메서드를 종료하라는 의미가 됩니다.

    data() 메서드는 int형 3의 값을 반환하고, sum의 경우 a 와 b를 더한 실수형을 반환하게 됩니다.

    이처럼 처리후 결과로 반환받고자 하는 자료형으로 리턴 타입을 결정해주면 됩니다.



    3) 클래스 외부에서 메서드 호출하기

    메서드도 클래스의 멤버이므로 객체 안에 존재하고, 클래스 외부에서 메서드를 사용하려면 먼저 객체를 생성해야 합니다.

    객체의 참조 변수를 이용해 메서드를 호출해야 합니다.

    위의 print(), data(), sum() 메서드를 클래스에 구성하여 클래스 외부에서 객체를 생성해 메서드를 호출해보겠습니다.

    class Test {
       void print() {
          System.out.println("Hello");
       }
       
       int data() {
          return 3;
       }
       
       double sum(int a, double b) {
          return a + b;
       }
       
       void printMonth(int m) {
          if (m < 1 || m > 12) {
             System.out.println("잘못된 입력입니다.");
             return;
          }
          System.out.println(m + "월 입니다.");
       }
    }
    
    public class JavaTest {
       public static void main(String[] args) {
          // 객체 생성
          Test t = new Test();
          
          // 메서드 호출
          t.print();
          int k = t.data();      
          System.out.println(k);
          double result = t.sum(2, 5.4);
          System.out.println(result);
          
          t.printMonth(3);
          t.printMonth(13);
       }
    }
    
    
    /// 결과 ///
    Hello
    3
    7.4
    3월 입니다.
    잘못된 입력입니다.

    Test 클래스를 t라는 참조 변수에 생성해 주었습니다. 그리고 객체의 메서드를 참조 변수에 포인트 연산자(.)를 이용해 호출해 주면 됩니다.

    print() 메서드를 호출하여 Hello가 출력되고 int k에 data()메서드에서 반환되는 3을 저장하여 출력해주어 3이 출력 되는 것을 볼 수 있습니다.

    이처럼 반환값을 저장할 변수를 동일한 자료형으로 만들고 저장하여 사용하면 됩니다.

    그리고 입력매개변수가 있는 메서드를 호출할 때는 해당 자료형의 값을 넘겨주어야 합니다.

    sum() 메서드의 경우 int 형과 double형이므로 2와 5.4를 순서에 맞게 넘겨주어 7.4라는 결과를 얻을 수 있게 됩니다.

    printMonth() 1~12월 까지만 제대로 나오고 그 외의 숫자에서는 잘못된 입력입니다를 출력후 return을하여 void 형에서 메서드를 종료되는 것을 볼 수 있습니다.


    4) 클래스 내부에서 메서드 호출하기

    이제 클래스 내부에서 메서드 간에 상호 호출할 때를 알아보겠습니다.

    클래스 내부에 있는 메서드끼리는 객체를 생성하지 않고 서로를 호출 할 수 있습니다.

    같은 멤버이기 때문에 필드 또한 멤버이므로 클래스 내부의 모든 메서드 안에서 객체를 생성하지 않고 자신이 속한 클래스의 필드를 사용할 수 있습니다.

    public class JavaTest {
       public static void main(String[] args) {
          print();
          
          int a = twice(3);
          System.out.println(a);
          
          double b = sum(a, 3.3);
          System.out.println(b);
       }
       
       public static void print() {
          System.out.println("Hello");
       }
       
       public static int twice(int k) {
          return k * 2;
       }
       
       public static double sum(int m, double n) {
          return m + n;
       }
    }
    
    
    
    /// 결과 ///
    Hello
    6
    9.3

    같은 클래스 안에 있는 메서드를 전부 바로 호출한 것을 볼 수 있습니다.



    5) 입력매개변수가 배열인 메서드 호출하기

    매개변수가 배열인 경우의 메서드에 대해 알아보겠습니다.

    public static void main(String[] args) {
       printArray(new int[] {1, 2, 3});
       
       int[] a = new int[] {1, 2, 3};
       printArray(a);
    }
    
    public static void printArray(int[] a) {
       System.out.println(Array.toString(a));
    }

    printArray() 메서드는 입력매개변수로 int[] 자료형으로 되어 있습니다.

    따라서 이 메서드를 호출하기 위해서는 int[] 객체를 생성해 입력매개변수로 넘겨 주어야 합니다.

    반드시 객체를 생성하여 넘겨주어야 한다는 점을 기억해야합니다.


    6) 기본 자료형 입력매개변수와 참조 자료형 입력매개변수의 차이

    배열과 같은 참조 자료형이 입력매개변수로 넘겨질 때는 실제 객체가 전달되는 것이 아니라 객체의 위치값이 전달됩니다.

    그 결과, 기본 자료형이 입력매개변수로 넘겨질 때와 다른 동작을 수행합니다.

    public static void main(String[] args) {
       int a = 3;
       int b1 = twice(3);
       int b2 = twice(a);
    }
    
    public static int twice(int a) {
       a = a * 2;
       return a;
    }

    기본 자료형일 때는 실제 값이 전달됩니다. 좀더 정확히 얘기하자면 기본 자료형의 값이 메서드의 지역 변수에 복사가 됩니다.

    [ 그림 1 : 스택 메모리 구조 ]

     twice(3)의 호출로 넘겨진 값 3은 twice() 메서드의 지역 변수 a에 복사되고, a 값을 두배로 곱한 값을 a값으로 저장한 후에 리턴합니다. 그래서 b1의 값은 6이 됩니다.

    b2는 a 값을 twice() 메서드의 입력으로 넘겨줬습니다. 그러면 twice()메서드에서는 twice메서드의 지역번수 a 에 main 메서드의 a 변수 값을 복사합니다.

    중요한 것은 twice() 메서드를 모두 호출한 뒤에도 main() 메서드의 a 값은 3으로 변화가 없습니다.

    이처럼 기본 자료형을 입력매개변수로 전달하면 전달 받은 메서드는 값을 복사하여 사용합니다.

    다음으로 참조 자료형을 입력매개변수로 넘기는 경우를 알아보겠습니다.

    public static void main(String[] args) {
       int [] array = new int[] {1, 2, 3};
       modifyData(array);
       printArray(array);	// {4, 5, 6}
    }
    
    public static void modifyData(int[] a) {
       a[0] = 4;
       a[1] = 5;
       a[2] = 6;
       
       // printArray(a);	// {4, 5, 6}
    }
    
    public static void printArray(int[] a) {
       System.out.println(Arrays.toString(a));		// {4, 5, 6}
    }

    참조 변수를 메서드로 넘기더라도 스택 메모리 값이 복사되어 사용되는 것은 동일합니다.

    하지만 복사되는 참조 자료형에 스택 메모리의 객체의 위치값이 저장되어 있기 때문에 같은 위치를 바라보게 됩니다.

    그래서 호출된 메서드에서 객체의 값을 변경후 호출한 메서드로 돌아오면 객체의 값이 바뀌어 있게 됩니다.

    [ 그림 2 : 참조 자료형이 전달됐을 때의 스택 메모리 구조 ]


     


    7) 메서드 오버로딩

    메서드는 앞서 알아봤듯이 메서드명과 입력매개변수로 구분하여 정의됩니다.

    자바 가상 머신은 메서드 매개변수가 다르고 메서드 명이 동일해도 다른 메서드로 인식합니다.

    메서드 오버로딩은 이러한 특징을 이용한 것으로, 입력매개변수의 개수나 자료형이 다른 여러 개의 동일한 이름을 지닌 메서드를 같은 공간에 정의하는 것을 말합니다.

    public static void main(String[] args) {
       print();
       
       print(3);
       
       print(3.7);
       
       print(2,4);
    }
    
    public static void print() {
       System.out.println("데이터가 없습니다.");
    }
    
    public static void print(int a) {
       System.out.println(a);
    }
    
    public static void print(double a) {
       System.out.println(a);
    }
    
    public static void print(int a, int b) {
       System.out.println(a + ", " + b);
    }

     4개의 print()메서드가 오버로딩되어 있습니다. 서로 다른 입력매개변수의 개수나 타입으로 정의되었다는 것을 알 수 있습니다.

    호출할 때 넘겨주는 매개변수에 따라 호출될 메서드가 선택됩니다.

    대표적으로 System.out.println() 메서드가 오버로딩된 메서드라고 볼 수 있습니다.

    그래서 문자열을 넘겨도 출력이 되고, 정수나 실수를 넘겨도 문제없이 출력이 되었던 것입니다.


    8) 가변 길이 배열 입력매개변수 메서드

    메서드를 정의할 때 입력매개변수의 개수가 몇개가 될지 정확히 모르는 경우, 가변 길이 배열로 입력 매개변수를 전달 받아야 합니다.

    배열은 1개의 자료형만 묶어 저장할 수 있으므로 입력되는 모든 값은 같은 자료형이여야 합니다.

    public static void main(String[] args) {
       method1(1, 2);
       method1(1, 2, 3);
       method1();
       
       method2("가", "나");
       method2("가", "나", "다");
       method2();
    }
    
    public static void method1(int... values) {
       System.out.println("입력매개변수 길이 : " + values.length);
       for (int i = 0; i < values.length; i++)
          System.out.print(values[i] + " ");
       System.out.println();
    }
    
    public static void method2(String... values) {
       System.out.println("입력매개변수 길이 : " + values.length);
       for (int i = 0; i < values.length; i++)
          System.out.print(values[i] + " ");
       System.out.println();
    }

    method1(int... values)는 개수와 상관없이 정수를 입력으로 받을 수 있고, method2(String... values)는 개수와 상관없이 문자열을 입력으로 받을 수 있습니다.

    매개변수의 개수가 달라질 경우 여러개의 오버로딩으로 구현해야할 일을 가변 길이 배열 입력매개변수를 사용하면 1개의 메서드만 정의해서 사용할 수 있습니다.

     

    좋아요 ♥ + 구독 부탁드려요 : )

    728x90
    반응형

    댓글