관리 메뉴

나만을 위한 블로그

[JAVA] 메서드란? 본문

JAVA

[JAVA] 메서드란?

참깨빵위에참깨빵 2020. 12. 13. 02:12
728x90
반응형

이번 포스팅에선 이래저래 자주 써왔던 메서드에 대해서 정리해보려고 한다.

먼저 메서드는 영어로 method라고 쓴다. 메소드라고도 읽는 사람들이 간혹 있다. 메서드라고 읽는 게 입을 덜 움직이기 때문에 난 메서드라고 읽는다

그리고 메서드와 함수는 엄밀히 따지면 다른 뉘앙스의 단어다. 자세한 내용은 아래 참고

onlyfor-me-blog.tistory.com/230

 

메서드 vs 함수

함수(Function) : 특정 작업을 수행하는 코드들의 모음 메서드(Method) : 클래스에 종속되어 존재하는 코드들의 모음 함수의 예시는 아래와 같다. 위 코드는 자바스크립트의 함수 중 하나를 가져온 것

onlyfor-me-blog.tistory.com

 

그럼 먼저 영문 위키백과에선 메서드를 어떻게 정의하는지 확인해보자.

어지간한 프로그래밍 언어라면 다 갖고 있는 게 메서드니, 정의를 찾는 건 굳이 자바에만 한정짓지 않아도 될 것 같다.

 

객체 지향 프로그래밍(OOP)의 메서드는 메시지 및 객체와 관련된 절차다. 객체는 데이터와 동작으로 구성된다. 이들은 다양한 소비자가 객체를 어떻게 활용할 수 있는지를 지정하는 인터페이스로 구성된다. 데이터는 객체의 속성으로 표시되고 동작은 메서드로 표시된다. 예를 들어 Window 객체는 open, close와 같은 메서드를 가질 수 있으며 상태(특정 시점에서 열려 있거나 닫혀 있는지 여부)는 속성이 된다. 클래스 기반 프로그래밍에서 메서드는 클래스에 정의되고 객체는 주어진 클래스의 인스턴스다. 메서드가 제공하는 가장 중요한 기능 중 하나는 메서드 재정의다. 같은 이름을 여러 종류의 클래스에 사용할 수 있다. 이를 통해 보내는 객체가 메서드를 호출하고 해당 동작의 구현을 수신 객체에 위임할 수 있다. 자바 프로그래밍의 메서드는 클래스 객체의 동작을 설정한다. 또한 메서드는 다른 클래스가 객체의 속성에 접근하고 수정하는 데 사용하는 인터페이스를 제공한다. 이걸 캡슐화라고 한다. 캡슐화, 재정의는 메서드와 프로시저 호출을 구분하는 2가지 주요 기능이다.

 

메서드를 말하려면 클래스를 먼저 알아야 한다. 왜냐면 위키백과에서 말하듯 메서드는 클래스에 정의되는(속하는) 요소기 때문이다.

보통 클래스는 아래와 같은 형태를 하고 있다.

 

public class Person
{
    /* 변수 */
    int age;
    String name;

    /* 메서드 */
    public void eat()
    {
        // eat()이 실행될 때 작업할 내용을 여기에 작성
    }
}

 

사람이라는 클래스를 만들고 이 안에 변수 2개와 메서드 1개를 정의했다.

클래스에 메서드를 정의하려면 먼저 접근 제어자를 설정한다. 접근 제어자는 private, default, protected, public 4가지 중 하나를 사용한다. 이걸 별도로 설정하지 않으면 기본으로 default 접근 제어자가 붙은 것으로 간주된다.

private가 붙은 변수, 메서드는 그 클래스에서만 접근할 수 있다.

default가 붙은 변수, 메서드는 해당 패키지 안에서만 접근할 수 있다.

protected가 붙은 변수, 메서드는 같은 패키지 안의 클래스 또는 그 클래스를 상속받은 외부 패키지의 클래스에서 접근이 가능하다.

public이 붙은 변수, 메서드는 어떤 클래스에서든 접근할 수 있다.

 

접근 제어자를 정했다면 static을 붙일지 말지를 정한다.

static이란 정적인, 움직이지 않는다 라는 뜻이 있는 영단어다. 자바의 static은 모든 객체가 공유할 수 있다는 의미로 사용되는 키워드다.

이 키워드는 모든 객체가 어떤 데이터에 접근해야 할 때 붙여서 사용할 수 있다. 그래서 멀티쓰레드 프로그램을 작성 시 공유 객체를 설정할 때 사용되곤 한다. 참고로 static이 붙으면 클래스를 객체화하지 않더라도 사용 가능하다.

여기선 eat()이 모든 객체가 접근해야 하는 공통요소가 아니기 때문에 static을 붙이지 않았다.

 

다음으로 메서드의 리턴값을 정한다.

리턴값이란 메서드 안에서만 사용하는 값으로, 메서드 안쪽에서 가공되어 메서드 밖으로 내보내진 값을 말한다.

위의 eat()에서 리턴값이 100, 4114같은 정수라면 int, "티스토리" 혹은 "컴퓨터" 같은 문자열이라면 String을 쓴다. 만약 리턴값이 없고 메서드 안에서 처리되기만 하고 끝날 뿐이라면 void를 써서 리턴값이 없음을 명시한다.

 

그 다음으로 메서드의 이름을 정한다. 사실 여기서 시간이 좀 걸리기도 한다. 작명이 제일 어렵다.

위의 예시에선 먹는다는 의미의 eat을 차용해서 eat()이라는 메서드를 만들었다.

 

eat 뒤의 () 안에는 eat 메서드가 작동할 때 필요한 값들을 명시해준다. 이를 인자, 파라미터, 매개변수라고 부른다.

이 인자의 선언은 메서드 안이나 밖 둘 중 어디에나 해도 무관하다. 메서드 안에서 인자를 설정한다면 메서드 안에서만 사용되고 메서드의 작업이 끝나면 삭제되는 지역변수가 된다. 메서드 밖, 즉 클래스 안에서 선언된 변수를 가져다 쓴다면 이 변수는 전역변수가 된다.

 

설명은 여기서 그만하고 eat()을 개조해보자. eat()에 인자로 String name, int age를 넣어서 "n살인 아무개는 음식을 먹는다"라는 문장을 만드는 것을 eat()의 작업 내용으로 설정한다고 치면 아래와 같이 메서드를 만들 수 있다.

 

public class Person
{
    /* 변수 */
    int age;
    String name;

    /* 메서드 */
    public void eat(String name, int age)
    {
        // eat()이 실행될 때 작업할 내용을 여기에 작성
        System.out.println(age + "살의 " + name + "은(는) 음식을 먹는다");
    }
}

인자의 순서를 name, age 순서대로 정했다면 호출했을 때도 저 순서에 맞게 각각 값을 넣어야 한다.

메인 메서드에서 호출해보자.

 

public class Main
{
    public static void main(String[] args)
    {
        Person person = new Person();
        person.eat("아무개", 14);
    }
}

 

Person 클래스의 eat()을 쓰기 위해서 Person 클래스의 객체를 만들었다.

그리고 이 객체를 통해 Person 클래스에 정의된 eat()을 호출한 뒤, 인자 순서대로 각각 값을 넣었다.

이 메인 클래스를 실행한다면 아래 결과가 콘솔에 출력된다.

 

 

eat()이 자기 역할을 잘 수행하고 종료된 걸 볼 수 있다.

 

그럼 이 메서드를 쓰는 목적은 무엇일까? 그냥 아무 이유 없이 메서드를 만들진 않았을 것이다.

메서드를 쓰는 목적은 중복되는 코드를 통한 코드량 뻥튀기, 반복되는 프로그래밍을 피하기 위함이다.

또한 중복되는 코드를 따로 메서드로 만들어 떼어냄으로서 코드 가독성도 올라갈 수 있다.

중복되는 코드의 뭐가 문제인지 감이 안 올 수 있으니 예시 하나를 들어보겠다.

 

public class Main
{
    public static void main(String[] args)
    {
        int age = 14;
        String name = "아무개";
        int age2 = 15;
        String name2 = "점순이";
        System.out.println(age + "살의 " + name + "은(는) 음식을 먹는다");
        System.out.println(age2 + "살의 " + name2 + "은(는) 잠을 잔다");
        // 이후 코드
    }
}

 

나이와 이름을 계속해서 정의해야 하고 이걸 출력하는 작업을 반복해야 하는 상황이 왔다고 가정하자.

메서드가 없다면 이것들을 메인 클래스에 변수명과 println()의 내용을 계속 바꿔가며 작성해야 할 것이다.

만약 자신이 이 작업을 해야 한다면 어떤 생각이 들까? 귀찮고 뭣보다 하기 싫을 것이다.

그래서 메서드를 통해 저 중에서 중복되는 코드들을 따로 떼서 클래스로 만들고 변수와 메서드를 정의한 다음, 메인에서 불러다 쓰면 코드량이 줄고 가독성도 훨씬 좋아진다.

위의 예시에 클래스와 메서드를 적용한다면 아래와 같이 될 것이다.

 

public class Main
{
    public static void main(String[] args)
    {
        Person person = new Person();
        Person person1 = new Person();
        person.eat("아무개", 14);
        person1.eat("점순이", 15);
    }
}

 

위와 비교해서 어떤가? eat()이 어떻게 작동하는지 알기만 한다면 좀 더 가독성이 좋아진 걸 느낄 수 있다.

뿐만 아니라 Person 클래스에 eat()을 한 번 정의해두기만 하면 eat()에 넣을 인자들의 수치만 바꿔서 계속 사용할 수 있다. eat() 자체가 어렵지 않은 메서드라 아직 와닿는 게 없을 수도 있지만, 복잡한 메서드를 만들거나 다뤄야 하는 경우가 오면 이것을 느낄 수 있을 것이다.

물론 Person의 객체를 계속 만들어야 한다는 단점이 있지만, 이 부분은 좀만 더 생각하거나 공부해보면 해결책을 찾을 수 있다.

 

 

정리

 

  • 메서드는 중복되는 코드가 생기는 걸 방지하고 다시 쓰기 위해서 사용한다
  • 메서드는 접근 제어자, 리턴값, 메서드 이름 (인자, 인자2, ...)의 형태로 선언한다. 중괄호 {} 안에는 이 메서드가 수행할 동작을 선언한다
  • 메서드를 만들려면 클래스가 있어야 한다. 클래스는 메서드와 변수라는 2가지 속성을 갖는다.
반응형
Comments