CodeGym /Java Blog /무작위의 /메소드 선언
John Squirrels
레벨 41
San Francisco

메소드 선언

무작위의 그룹에 게시되었습니다
안녕! 필드와 메서드를 사용하여 자신만의 클래스를 만드는 방법에 대해 이미 알고 있습니다. 이제 방법에 대해 살펴보겠습니다.
메소드 선언 - 1
물론 우리는 수업에서 이미 한 번 이상 이 작업을 수행했지만 주로 일반 사항을 다루었습니다. 오늘, 우리는 방법을 해부하고 그것이 무엇으로 구성되어 있는지, 그것을 만드는 다양한 방법 및 모든 것을 관리하는 방법을 연구할 것입니다. :) 갑시다!

메소드 선언

메서드를 정의하는 모든 코드를 메서드 선언 이라고 합니다 . 메서드 선언의 일반적인 형식은 다음과 같이 설명할 수 있습니다.

access modifier, return type, method name (parameter list) {
    // method body
}
예를 들어 클래스의 다양한 메서드 선언을 살펴보십시오 Dog.

public class Dog {

   String name;

   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {
       Dog max = new Dog("Max");
       max.woof();

   }

   public void woof() {
       System.out.println("A dog named " + name + " says \"Woof, woof!\"");
   }

   public void run(int distanceInFeet) {
       System.out.println("A dog named " + name + " ran " + distanceInFeet + " feet!");
   }

   public String getName() {
       return name;
   }
}

1. 액세스 수정자

액세스 한정자는 항상 먼저 표시됩니다. 클래스의 모든 메서드는 publicDog 한정자 로 표시됩니다 . 이는 다른 클래스에서 호출할 수 있음을 의미합니다.

public class Main {

   public static void main(String[] args) {

       Dog butch = new Dog("Butch");
       butch.run(100);
   }

}
보시 Dog다시피 클래스의 메서드는 클래스에서 쉽게 액세스할 수 있습니다 Main. 이는 public 한정자로 인해 가능합니다. Java에는 다른 수정자가 있습니다. 그들은 모두 다른 클래스에서 메서드를 사용하는 것을 허용하지 않습니다. 다른 수업에서 이에 대해 이야기하겠습니다. 기억해야 할 주요 사항은 수정자가 담당하는 것입니다: 다른 클래스에서 메서드에 액세스할 수 있는지 여부 :)

2. 정적 키워드

Dog메서드 중 하나는 staticmain() 키워드로 표시됩니다 . 그것은 또한 메서드 선언의 일부이며 우리는 이미 그 의미를 알고 있습니다. 선택 사항이기 때문에 강의 시작 부분에 제공된 메서드 선언 템플릿에서 언급하지 않았습니다. 지정된 경우 액세스 수정자 뒤에 와야 합니다. 최근 수업에서 정적(클래스) 변수에 대해 이야기한 것을 기억하십니까? 메서드에 적용할 때 이 키워드는 거의 같은 의미를 가집니다. 메서드가 정적 이면 클래스의 특정 개체에 대한 참조 없이 사용할 수 있습니다. 그리고 실제로 정적 메소드를 실행하기 위해 객체가 필요하지 않습니다.Dogmain()Dog수업. 없이도 잘 실행됩니다. 이 메소드가 정적이 아닌 경우 이를 실행하기 위해 먼저 오브젝트를 작성해야 합니다.

3. 반환 값

메서드가 무언가를 반환해야 하는 경우 반환 값의 유형을 지정합니다. 이것은 게터의 예에서 분명합니다 getName().

public String getName() {
   return name;
}
객체를 반환합니다 String. 메서드가 아무 것도 반환하지 않으면 메서드에서와 같이 void 키워드가 대신 사용됩니다 woof().

public void woof() {
   System.out.println("A dog named " + name + " says \"Woof, woof!\"");
}

이름이 같은 메서드

메서드를 호출하는 데 여러 가지 다른 방법이 필요한 상황이 있습니다. 우리 자신의 인공 지능을 만들어 보지 않겠습니까? Amazon에는 Alexa가 있고 Apple에는 Siri가 있습니다. 그렇다면 우리는 왜 그것을 가지면 안 됩니까? :) 영화 아이언맨에서 토니 스타크는 자신만의 놀라운 인공 지능인 자비스를 만듭니다. 그 멋진 캐릭터에게 경의를 표하고 그의 이름을 기리기 위해 우리 AI의 이름을 지정합시다. :) 가장 먼저 해야 할 일은 Jarvis에게 방에 들어오는 사람들에게 인사하는 법을 가르치는 것입니다.

public class Jarvis {

   public void sayHi(String name) {
       System.out.println("Good evening, " + name + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
   }
}
콘솔 출력: 안녕하세요, Tony Stark. 어떻게 지내세요? 매우 좋은! 자비스는 이제 손님을 맞이할 수 있습니다. 물론 그의 주인인 토니 스타크보다 더 자주. 하지만 그가 혼자 오지 않는다면 어떨까요! 그러나 우리의 sayHi()방법은 하나의 인수만 허용합니다. 따라서 방에 들어오는 한 사람에게만 인사할 수 있고 다른 사람은 무시합니다. 매우 예의 바르지 않습니까? :/ 이 경우 이름은 같지만 매개변수가 다른 2개의 메서드를 작성하여 문제를 해결할 수 있습니다.

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

}
이를 메서드 오버로딩 이라고 합니다 . 메서드 오버로딩을 통해 프로그램이 더 유연해지고 다양한 작업 방식을 수용할 수 있습니다. 작동 방식을 검토해 보겠습니다.

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
콘솔 출력: 안녕하세요, Tony Stark. 어떻게 지내세요? 좋은 저녁입니다, 토니 스타크와 캡틴 아메리카. 어떻게 지내세요? 훌륭합니다. 두 버전 모두 작동했습니다. :) 그러나 우리는 문제를 해결하지 못했습니다! 손님이 3명이라면? 물론 sayHi()세 개의 게스트 이름을 허용하도록 메서드를 다시 오버로드할 수 있습니다. 하지만 4개 또는 5개가 있을 수 있습니다. 무한대까지. sayHi()메서드를 백만 번() 오버로드하지 않고 Jarvis에게 여러 이름을 처리하도록 가르치는 더 좋은 방법이 없습니까 ? :/ 물론 있습니다! 그렇지 않다면 Java가 세계에서 가장 인기 있는 프로그래밍 언어가 될 것이라고 생각하십니까? ;)

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       System.out.println();
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
( String... names )가 매개변수로 사용되면 문자열 모음이 메서드에 전달됨을 나타냅니다. 얼마나 많은지 미리 지정할 필요가 없으므로 이제 방법이 훨씬 더 유연해졌습니다.

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
   }
}
콘솔 출력: 안녕하세요, Tony Stark. 어떻게 지내세요? 좋은 저녁입니다, 캡틴 아메리카. 어떻게 지내세요? 좋은 저녁입니다, 블랙 위도우. 어떻게 지내세요? 좋은 저녁입니다, 헐크. 어떻게 지내세요? 메서드 내에서 모든 인수를 반복하고 이름으로 형식이 지정된 구문을 표시합니다. 여기서는 단순화된 루프를 사용합니다 for-each(이전에 본 적이 있음). ( String... names ) 표기법은 실제로 컴파일러가 전달된 모든 인수를 배열에 넣는 것을 의미하기 때문에 여기에서 완벽합니다 . 결과적으로 변수 이름 으로 작업할 수 있습니다.루프에서 배열을 반복하는 것을 포함하여 배열로 작업하는 것과 같습니다. 또한 전달된 문자열 수에 관계없이 작동합니다! 2명, 10명, 심지어 1000명까지 - 이 방법은 손님의 수에 관계없이 적절하게 작동합니다. 모든 가능성에 대해 방법을 오버로드하는 것보다 훨씬 편리하다고 생각하지 않습니까? :) 다음은 메서드 오버로딩의 또 다른 예입니다. Jarvis에게 메소드를 제공합시다 printInfoFromDatabase(). 데이터베이스에서 사람에 대한 정보를 표시합니다. 데이터베이스에 어떤 사람이 슈퍼히어로 또는 슈퍼악당이라고 표시되면 해당 정보가 표시됩니다.

public class Jarvis {

   public void printInfoFromDatabase (String bio) {

       System.out.println(bio);
   }

   public void printInfoFromDatabase(String bio, boolean isEvil, String nickname) {

       System.out.println(bio);
       if (!isEvil) {
           System.out.println("Also known as the superhero " + nickname);
       } else {
           System.out.println("Also known as the supervillain " + nickname);
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.printInfoFromDatabase("Laura Palmer. Date of birth: July 22, 1972. Twin Peaks, Washington");
       System.out.println();
       jarvis.printInfoFromDatabase("Max Eisenhardt. Height: 15.6 ft. Weight: 189 lbs. ", true, "Magneto");
   }
}
출력: 로라 팔머. 생년월일: 1972년 7월 22일. 트윈 픽스, 워싱턴 Max Eisenhardt. 높이: 15.6피트 무게: 189파운드 슈퍼 악당 매그니토라고도 알려져 있으므로 , 우리 메서드의 동작은 우리가 전달하는 데이터에 따라 달라집니다. 여기에 또 다른 중요한 점이 있습니다. 인수의 순서가 중요합니다! 메서드가 문자열과 숫자를 받는다고 가정해 보겠습니다.

public class Person {

   public static void sayYourAge(String greeting, int age) {
       System.out.println(greeting + " " + age);
   }

   public static void main(String[] args) {

       sayYourAge("My age is ", 33);
       sayYourAge(33, "My age is "); // Error!
   }
}
Person클래스의 메서드가 문자열과 숫자를 입력으로 사용하는 경우 sayYourAge()이러한 인수가 메서드에 전달되어야 하는 순서입니다! 다른 순서로 전달하면 컴파일러에서 오류가 발생하고 사용자는 자신의 나이를 말할 수 없습니다. 그건 그렇고, 지난 수업에서 다룬 생성자도 메서드입니다! 또한 그것들을 오버로드할 수 있으며(즉, 매개 변수 집합이 다른 여러 생성자를 생성) 전달된 인수의 순서도 근본적으로 중요합니다. 그들은 실제 방법입니다! :)

유사한 매개변수를 사용하여 메소드를 호출하는 방법

아시다시피 nullJava의 키워드입니다. null객체도 데이터 유형도 아니라는 점을 이해하는 것이 매우 중요합니다 . 사람의 이름과 나이를 알리는 Person클래스와 메소드가 있다고 상상해 보십시오 . introduce()또한 나이는 텍스트 또는 숫자로 전달할 수 있습니다.

public class Person {

   public void introduce(String name, String age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person alex = new Person();
       alex.introduce ("Alex", "twenty-one");

       Person mary = new Person();
       mary.introduce("Mary", 32);
   }
}
우리는 이미 오버로드에 익숙하므로 두 메서드가 모두 정상적으로 작동한다는 것을 알고 있습니다. 내 이름은 Alex입니다. 내 나이 스물한 살 내 이름은 Mary입니다. 내 나이 32세null 인데 문자열이나 숫자가 아닌 두 번째 매개변수로 전달하면 어떻게 될까요 ?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
컴파일 오류가 발생합니다! 이 문제의 원인은 무엇이며 "모호함"은 정확히 무엇입니까? 사실, 그것은 모두 매우 간단합니다. 문제는 메서드의 두 가지 버전이 있다는 것입니다. 하나는 String두 번째 인수로 a를 사용하고 다른 하나는 Integer두 번째 인수로 an을 사용합니다. 그러나 a String와 an은 Integer둘 다 될 수 있습니다 null! 참조 유형이기 때문에 null둘 다 기본값입니다. 그렇기 때문에 이 상황에서 컴파일러는 호출해야 하는 메서드의 버전을 파악할 수 없습니다. 이 문제에 대한 해결책은 아주 간단합니다. Null특정 참조 형식으로 명시적으로 변환할 수 있습니다. 따라서 메소드를 호출할 때 두 번째 인수에 대해 원하는 데이터 유형을 괄호 안에 표시할 수 있습니다! 컴파일러는 "힌트"를 이해하고 올바른 메서드를 호출합니다.

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Method with a string and a number!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", (String) null);
   }
}
출력: 문자열이 두 개인 메서드! 제 이름은 빅터입니다. 내 나이는 null입니다. number 매개변수가 Integer 참조 유형의 인스턴스가 아니라 primitive 인 경우 int이러한 오류가 발생하지 않습니다.

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, int age) {
       System.out.println("Method with a string and a number!!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", null);
   }
}
이유를 짐작할 수 있습니까? 이유를 추측했다면 잘하셨습니다! :) 프리미티브는 null. 이제 컴파일러는 하나의 선택, 즉 introduce()두 개의 문자열로 메서드를 호출할 수 있습니다. 이것은 메소드가 호출될 때마다 실행될 메소드의 버전입니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION