[Java]메소드

Devlog·2024년 3월 12일

Java

목록 보기
14/41

메소드

리턴타입 메소드이름 ( [매개변수선언, ···]) {
  실행할 코드를 작성하는 곳
}

- 리턴 타입: 메소드가 리턴하는 결과의 타입을 표시함
- 메소드 이름: 메소드의 기능이 드러나도록 식별자 규칙에 맞게 이름을 지어줘야함
- 매개 변수 선언: 메소드를 실행할 때 필요한 데이터를 받기 위한 변수를 선언
- 메소드 실행 블록: 실행할 코드를 작성


✔️ 메소드 선언

: 선언부(리턴 타입, 메소드 이름, 매개 변수 선언)와 실행 블록으로 구성됨

- 리턴 타입
: 리턴값의 타입
: 리턴값이란 메소드를 실행한 후의 결과값

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) 문

- 리턴값이 있는 메소드

return 리턴값;

: 메소드 선언에 리턴 타입이 있는 메소드는
  반드시 리턴문을 사용해서 리턴값을 지정해야함

ex)
int plus(int x, int y){
	int result = x+y;
	return result;
}

- 리턴값이 없는 메소드: void

return;

: 리턴값이 없는 메소드는 리턴 타입으로 void를 사용
: void로 선언된 메소드에서도 return문을 사용가능
  → 리턴값을 지정하는 것이 아니라 메소드 실행을 강제 종료시키는 역할

👩‍💻 returnclass 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) { ··· }

0개의 댓글