리턴타입 메소드이름 ( [매개변수선언, ···]) {
실행할 코드를 작성하는 곳
}
- 리턴 타입: 메소드가 리턴하는 결과의 타입을 표시함
- 메소드 이름: 메소드의 기능이 드러나도록 식별자 규칙에 맞게 이름을 지어줘야함
- 매개 변수 선언: 메소드를 실행할 때 필요한 데이터를 받기 위한 변수를 선언
- 메소드 실행 블록: 실행할 코드를 작성
: 선언부(리턴 타입, 메소드 이름, 매개 변수 선언)와 실행 블록으로 구성됨
- 리턴 타입
: 리턴값의 타입
: 리턴값이란 메소드를 실행한 후의 결과값
ex) 전자계산기 객체
> 전원 버튼[powerOn() 메소드]
- 전원을 켜고 끄는 기능 실행
- 리턴값 없음
- 리턴 타입으로 void지정
→ void powerOn() { ... }
→ 메소드 호출 시, powerOn()
> 나누기 버튼[divide() 메소드]
- 나누는 기능
- 리턴값은 나눗셈 결과
- 리턴 타입으로 double 지정
→ double divide(int x, int y) { ... }
→ 메소드 호출 시, double result = divide(10,20);
리턴값이 중요하지 않고 메소드 실행이 중요한 경우
→ 메소드 호출 시, divide(10,20)
👩💻 메소드 선언
//Calculator.java
public class Calculator {
//메소드
void powerOn() {
System.out.println("전원을 켭니다.");
}
int plus(int x, int y) {
int result = x + y;
return result;
}
double divide(int x, int y) {
double result = (double)x / (double)y;
return result;
}
void powerOff() {
System.out.println("전원을 끕니다.");
}
}
//CalculatorExample.java
public class CalculatorExample {
public static void main(String[] args) {
Calculator myCalc = new Calculator();
myCalc.powerOn();
int result1 = myCalc.plus(5,6);
System.out.println("result1: " + result1);
byte x = 10;
byte y = 4;
double result2 = myCalc.divide(x, y);
System.out.println("result2: " + result2);
myCalc.powerOff();
}
}
💻결과
전원을 켭니다.
result1: 11
result2: 2.5
전원을 끕니다.
- 매개 변수의 개수를 모를 경우
[해결방법]
1. 매개 변수를 배열 타입으로 선언하는 것
ex)
// 배열 타입으로 선언
int sum1(int[] values){ }
// sum1() 메소드 호출하기
int[] valuse = {1,2,3};
int result = sum1(values);
int result = sum1(new int[] {1,2,3,4,5});
2. 값의 목록만 넘겨주기
: 매개 변수를 ...를 사용해서 선언하게 되면 메소드 호출 시
넘겨준 값의 수에 따라 자동으로 배열이 생성되고 매개값으로 사용됨
ex)
// 매개 변수를 ... 로 선언
int sum2(int ... values) { }
// sum2() 메소드 호출하기
// ...로 선언된 매개 변수의 값은 메소드 호출 시 쉼표로 나열해주면됨
int result = sum2(1, 2, 3);
int result = sum2(1, 2, 3, 4, 5);
// ...로 선언된 매개 변수는 배열 타입이므로
// 다음과 같이 배열을 직접 매개값으로 사용해도 좋음
int[] valuse = {1,2,3};
int result = sum1(values);
int result = sum1(new int[] {1,2,3,4,5});
👩💻 매개 변수의 개수를 모를경우
class Computer{
int sum1(int[] values) {
int sum = 0;
for(int i=0; i < values.length; i++) {
sum += values[i];
}
return sum;
}
int sum2(int ... values) {
int sum = 0;
for(int i = 0; i < values.length; i++) {
sum += values[i];
}
return sum;
}
}
public class ComputerExample {
public static void main(String[] args) {
Computer myCom = new Computer();
int[] values1 = {1, 2, 3};
int result1 = myCom.sum1(values1);
System.out.println("result1: "+result1);
int result2 = myCom.sum1(new int[] {1, 2, 3, 4, 5});
System.out.println("result2: "+result2);
int result3 = myCom.sum2(1, 2, 3);
System.out.println("result3: "+result3);
int result4 = myCom.sum2(1, 2, 3, 4, 5);
System.out.println("result4: "+result4);
}
}
💻 결과
result1: 6
result2: 15
result3: 6
result4: 15
- 리턴값이 있는 메소드
return 리턴값;
: 메소드 선언에 리턴 타입이 있는 메소드는
반드시 리턴문을 사용해서 리턴값을 지정해야함
ex)
int plus(int x, int y){
int result = x+y;
return result;
}
- 리턴값이 없는 메소드: void
return;
: 리턴값이 없는 메소드는 리턴 타입으로 void를 사용함
: void로 선언된 메소드에서도 return문을 사용가능함
→ 리턴값을 지정하는 것이 아니라 메소드 실행을 강제 종료시키는 역할
👩💻 return문
class Car {
//필드
int gas;
//생성자
//메소드
void setGas(int gas) {
this.gas = gas;
}
boolean isLeftGas() {
if(gas == 0) {
System.out.println("gas가 없습니다.");
return false;
}
System.out.println("gas가 있습니다.");
return true;
}
void run() {
while(true) {
if(gas > 0) {
System.out.println("달립니다.(gas잔량:" + gas + ")");
gas -= 1;
} else {
System.out.println("멈춥니다.(gas잔량:" + gas + ")");
return;
}
}
}
}
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car();
myCar.setGas(5); //Car의 setGas() 메소드 호출
boolean gasState = myCar.isLeftGas(); //Car의 isLeftGas() 메소드 호출
if(gasState) {
System.out.println("출발합니다.");
myCar.run(); //Car의 run() 메소드 호출
}
if(myCar.isLeftGas()) { //Car의 isLeftGas() 메소드 호출
System.out.println("gas를 주입할 필요가 없습니다.");
}else {
System.out.println("gas를 주입하세요.");
}
}
}
💻 결과
gas가 있습니다.
출발합니다.
달립니다.(gas잔량:5)
달립니다.(gas잔량:4)
달립니다.(gas잔량:3)
달립니다.(gas잔량:2)
달립니다.(gas잔량:1)
멈춥니다.(gas잔량:0)
gas가 없습니다.
gas를 주입하세요.
- 클래스 내부의 다른 메소드에서 호출할 경우에는
단순한 메소드 이름으로 호출하면 됨
클래스 외부에서 호출할 경우에는
우선 클래스로부터 객체를 생성한 뒤 참조 변수를 이용해서 메소드를 호출해야함
객체가 존재해야 메소드도 존재하기 때문
- 객체 내부에서 호출
메소드( 매개값, ··· );
public class ClassName {
void method1( String p1, int p2 ) {
// 2. 실행 시
// p1 - 홍길동, p2 - 100
}
void method2() {
// 1. 호출
method1("홍길동", 100);
}
}
- 변수를 선언하고 리턴값을 대입
타입 변수 = 메소드(매개값, ···);
public class ClassName{
int method1(int x, int y){
int result = x+y;
return result;
}
void method2(){
int result1 = method1(10, 20);
double result2 = method1(10, 20);
}
}
👩💻 클래스 내부에서 메소드 호출
class Calculator2 {
// 2. plus() 메소드 실행
int plus(int x, int y) {
int result = x + y;
return result; // return값을 execute()메소드로 리턴값을 줌
}
// 1. avg() 메소드 실행
double avg(int x, int y) {
double sum = plus(x, y);
double result = sum / 2;
return result;
}
void execute() {
double result = avg(7, 10);
println("실행결과: " + result);
}
// 3. execute() 리턴값 받고 println()메소드를 호출할 떄 매개값으로 넘겨줌
void println(String message) {
System.out.println(message);
}
}
public class CalculatorExample2 {
public static void main(String[] args) {
Calculator2 myCalc = new Calculator2();
myCalc.execute();
}
}
💻 결과
실행결과: 8.5
- 객체 외부에서 호출
- 객체가 존재하지 않을 시
클래스 참조변수 = new 클래스(매개값, ··· );
- 객체가 생성됐을 시
//리턴값이 없거나, 있어도 리턴값을 받지 않을 경우
참조변수.메소드(매개값, ··· );
//리턴값이 있고, 리턴값을 받고 싶을 경우
타입 변수 = 참조변수.메소드(매개값, ··· );
👩💻 클래스 외부에서 메소드 호출
class Car2{
//필드
int speed;
//생성자
//메소드
int getSpeed() {
return speed;
}
void keyTurnOn() {
System.out.println("키를 돌립니다.");
}
void run() {
for(int i=10; i<=50; i+=10) {
speed = i;
System.out.println("달립니다.(시속:"+speed+"km/h"+")");
}
}
}
public class CarExample2 {
public static void main(String[] args) {
Car2 myCar = new Car2();
myCar.keyTurnOn();
myCar.run();
int speed = myCar.getSpeed();
System.out.println("현재 속도: "+speed+"km/h");
}
}
💻 결과
키를 돌립니다.
달립니다.(시속:10km/h)
달립니다.(시속:20km/h)
달립니다.(시속:30km/h)
달립니다.(시속:40km/h)
달립니다.(시속:50km/h)
현재 속도: 50km/h
: 클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것
조건
: 매개 변수의 타입, 개수, 순서 중 하나가 달라야 함
class 클래스 {
// 리턴 타입 - 상관없음
// 메소드이름 - 동일
// 타입변수 - 매개 변수의 타입, 개수, 순서 다름
리턴 타입 메소드이름 (타입 변수, ···) { ··· }
리턴 타입 메소드이름 (타입 변수, ···) { ··· }
}
ex)
int plus(int x, int y){
int result = x + y;
return result;
}
double plus(double x, double y){
double result = x + y;
return result;
}
// 오버로딩된 메소드를 호출할 경우 JVM은 매개값의 타입을 보고 메소드를 선택함
// 매개값이 정수이므로 plus(int x, int y) 메소드가 실행됨
plus(10, 20);
// 매개값이 실수이므로 plus(double x, double y) 메소드가 실행됨
plus(10.5, 20.3);
int x = 10;
double y = 20.3;
plus(x,y);
위와 같은 코드 경우 plus(double x, double y) 메소드가 실행됨
JVM은 일차적으로 매개 변수의 타입을 보지만,
매개 변수의 타입이 일치하지 않을 경우 자동 타입 변화이 가능한지를 검사함
첫 번째 매개 변수인 int는 double 타입으로 변환이 가능하므로
최종적으로 plus(double x, double y)메소드가 선택됨
주의할 점
1. 매개 변수의 타입과 개수, 순서가 똑같을 경우 매개 변수 이름이 다르다고 해서
이것을 메소드 오버로딩이라고 하지 않음
2. 리턴 타입만 다르고 매개 변수가 동일하다면 이것도 오버로딩이 아님
→ 리턴 타입은 JVM이 메소드를 선택할 때 아무런 도움을 주지 못하기 때문
- 메소드 오버로딩의 가장 대표적인 예 System.out.println() 메소드
println()메소드는 호출할 때 주어진 매개값의 타입에 따라서
오버로딩된 println() 메소드 중 하나를 호출 함
void println() { ··· }
void println(boolean x) { ··· }
void println(char x) { ··· }
void println(char[] x) { ··· }
void println(double x) { ··· }
void println(float x) { ··· }
void println(int x) { ··· }
void println(long x) { ··· }
void println(Object x) { ··· }
void println(String x) { ··· }