본문 바로가기
👨‍💻 2. 웹개발_Back end/2-1 Java

[JAVA] 06-4 메소드

by 달님🌙 2021. 8. 2.
반응형
메소드 선언부

 

** 형태 

리턴타입 메소드이름 ( 매개변수 선언 ) {
	실 행 코 드 
}

 

** 종류 

1. 리턴 타입 : 리턴값(=메소드를 실행하고 난 후에 나오는 결과값)의 타입을 말함

- 리턴값이 없는 메소드는 리턴타입을 void로 기술한다. 메소드 호출 시 단순히 메소드만 호출하면 된다.

- 리턴값이 있는 메소드는 리턴타입에 해당 타입을 기술하며, 이 경우에는 값이 나오므로 메소드 호출 시 저장할만한 변수를 하나 선언해주어야한다. 

- 하지만 리턴값이 별로 중요하지않고 메소드 실행 자체가 중요할 경우, 변수를 굳이 선언하지 않고 메소드를 호출할 수 도 있다.

 

2. 메소드이름 (식별자 규칙)

- 어떤 기능을 담고 있는지 쉽게 알 수 있도록 이름 짓기

- 숫자로 시작할 수 없다.

- 특수문자 사용시 $와 _만 사용가능하다.

- 소문자로 작성하되 혼합이름의 경우 뒤 단어는 대문자로 시작

 

3. 매개변수 선언

- 필요한 데이터를 외부로부터 받을 수 있도록 해준다.

- 메소드 선언부에 작성해준 매개변수 타입과 메소드 호출 부분에서 사용할 값의 타입이 일치해야한다. 

- 일치하지않으면 컴파일 에러가 발생한다. 하지만 자동 타입 변환이 이루어지는 관계일 때는 에러가 발생하지 않는다.

 

4. 메소드 실행 블록

- 실행하고자 하는 코드를 메소드 실행 블록 안에 작성해준다.

 

계산기 예제

 

public class Calculator {
	public void powerOn () {
		System.out.println("전원을 켭니다.");
	}
	public int plus(int i, int j) {
		return i+j;
	}
	
	public void powerOff() {
		System.out.println("전원을 끕니다.");
	}
	public double divide(int i, int j) {
		if(j==0) {
			System.out.println("0으로 나눌 수 없습니다.");
		}
		return (double)i / j;
	}
}

 

public class CalculatorExample {
	public static void main(String[] args) {
		Calculator myCalc = new Calculator();
		
		// 계산기 켜기
		myCalc.powerOn();
		
		// 계산하기
		int var1 = myCalc.plus(8,8);
		System.out.println("var1 : " + var1);
		double var2 = myCalc.divide(4, 8);
		System.out.println("var2 :" + var2);
		
		byte x = 10;
		byte y = 4;
		double var3 = myCalc.divide(x,y);
		System.out.println("var3 : " + var3);
				
		// 계산기 끄기
		myCalc.powerOff();
	}
}

 

전원을 켭니다.
var1 : 16
var2 :0.5
var3 : 2.5
전원을 끕니다.

 

매개 변수의 개수를 모를 때

 

방법 1. 배열 타입으로 선언

방법 2. ' ... ' 이용하기

 

- 두 가지 방법을 예제로 살펴보기

public class Computer {
	// 방법1. 배열 이용
	int sum1(int[] arrs) {
		int total = 0;
		for(int i=0; i<arrs.length; i++) {
			total += arrs[i];
		}
		return total;
	}
	
    // 방법2. ... 이용
	int sum2(int ... values) {
		int total = 0;
		for(int i=0; i<values.length; i++) {
			total += values[i];
		}
		return total;
	}
}

 

public class ComputerExample {
	public static void main(String[] args) {
		Computer myCom = new Computer();
		
		int[] values1 = {1,2,3};
//				"100번지"
		
		int result1 = myCom.sum1(values1);
		System.out.println("myCom.sum(int[]) : " + result1); // 6
		
		int result2 = myCom.sum1(new int[] {1,2,3,4,5});
		System.out.println("myCom.sum(new int[]{}) : " + result2); // 15
		
		int result3 = myCom.sum2(1,2,3,4,5,6,7,8,9,10);
		System.out.println("myCom.sum2(int...values) : " + result3); // 55
		
		int result4 = myCom.sum2(1,2,3,4,5);
		System.out.println("result4: " + result4); // 15
	}	
}

 

 

- 위 예제 중복 코드 제거 버전

//중복된 코드 제거 버전
public class Computer2 {
	
	int[] intList;
	
	int sum() {
		return arraySum(this.intList);
	}
	int sum1(int[] arrs) {
		return arraySum(arrs);
	}
	int sum2(int...values) {
		return arraySum(values);
	}
	int arraySum(int[] ars) {
		int total = 0;
		for(int i=0; i<ars.length; i++) {
			total += ars[i];
		}
		return total;
	}
}

 

public class Computer2Example {
	public static void main(String[] args) {
//		중복코드 제거 버전
		Computer2 myCom = new Computer2();
	
		int[] values1 = {1, 2, 3}; // 아래에 번지 값을 넣어줌
		myCom.intList = values1;
		
		int result1 = myCom.sum1(values1);
		System.out.println("myCom.sum(int[]) : " + result1);
		
		int result2 = myCom.sum1(new int[] {1,2,3,4,5});
		System.out.println("myCom.sum(new int[]{}) : " + result2);
		
		int result3 = myCom.sum2(1,2,3,4,5,6,7,8,9,10);
		System.out.println("myCom.sum2(int...values) : " + result3);
	}
}

 

 

return 문 이후 실행문

 

- return문이 실행되면 메소드는 즉시 종료된다. 

- 따라서 그 뒤에 실행문이 온다면 'Unreachable code' 에러가 발생한다.

 

 

 

리턴값이 없는 메소드

 

- 리턴값이 없는 메소드는 리턴 타입으로 void를 사용한다.

- void를 사용해도 return문을 사용할 수 있는데 그 경우에는 값을 가져오는게 목적이 아닌 , 메소드 실행을 종료하려는 목적이다. 

 

return문 예제

 

public class Car1 {
	//필드
	int gas;
	
	//생성자
	
	//메소드
	
	// 연료충전 메소드
	void setGas(int gas) { // 리턴값이 없는 메소드로 매개값을 받아서 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.printf("주행중~~~[gas: %d]\n",gas);
				gas--;
			} else {
				System.out.printf("정지~!!!!~~[gas: %d]\n",gas);
				return; //메소드 실행 종료
			}
		}
	}
}

 

public class Car1Example {
	public static void main(String[] args) throws InterruptedException {
		Car1 myCar = new Car1();
		myCar.setGas(10);
		
		boolean gasState = myCar.isLeftGas();
		if(gasState) {
			System.out.println("출발합니다.");
			myCar.run();
		}
		
		if(myCar.isLeftGas() ) {
			System.out.println("gas를 주입할 필요가 없습니다.");
		} else {
			System.out.println("gas를 주입하세요.");
		}
	}
}

 

gas가 있습니다.
출발합니다.
주행중~~~[gas: 10]
주행중~~~[gas: 9]
주행중~~~[gas: 8]
주행중~~~[gas: 7]
주행중~~~[gas: 6]
주행중~~~[gas: 5]
주행중~~~[gas: 4]
주행중~~~[gas: 3]
주행중~~~[gas: 2]
주행중~~~[gas: 1]
정지~!!!!~~[gas: 0]
gas가 없습니다.
gas를 주입하세요.

 

메소드 호출

 

- 객체 내부에서 호출할 때는 그냥 메소드이름만 작성

- 객체 외부에서 호츨할 때는 객체 생성(new 이용) 후 참조 변수와 함께 도트(.)연산자 사용하여 호출한다.

 

- 리턴값이 없는 메소드는 그냥 메소드이름(매개값, ...); 로 호출

- 리턴값이 있는 메소드는 타입 변수 = 메소드이름(매개값, ...); 로 호출

 

계산기 예제 (객체 내부에서 호출)

 

public class Calculator {
	//메소드
	int plus(int x, int y) { // 합 메소드
		int result = x + y; 
		return result;
	}
	
	double avg(int x, int y) { // 평균 메소드
		double sum = x + y;
		double result = sum / 2;
		return result;
	}
	
	void execute() { // 기능 수행 메소드
		double result = avg(7,10);
		println("실행결과 : " + result);
	}
	
	void println(String message) { // 출력 메소드
		System.out.println(message);
	}
}

 

public class CalculatorExample {
	public static void main(String[] args) {
		Calculator myCarc = new Calculator();
		myCarc.execute(); // 실행결과 : 8.5
	}
}

 

 

Car 예제 (객체 외부에서 호출)

 

public class Car3 {
	//필드
	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 Car3Example {
	public static void main(String[] args) {
		Car3 myCar = new Car3();
		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

 

 

 

추가 예제 - Contact 클래스

 

class Contact {
	//필드
	String emailAddress;
	String faxNumber;
	String name;
	
	//메소드
	
	// 이름
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	// 이메일
	public String getEmailAddress() {
		return emailAddress;
	}
	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}
	
	// 팩스번호
	public String getFaxNumber() {
		return faxNumber;
	} 
	public void setFaxNumber(String faxNumber) {
		this.faxNumber = faxNumber;
	}
}

 

class ContactExample {
	
	public static void main(String[] args) {
		Contact con = new Contact();
		con.setName("김자바");
		System.out.println("이름 : " + con.getName()); // 이름 : 김자바
		con.setEmailAddress("abc@gmail.com");
		System.out.println("이메일 : " + con.getEmailAddress()); // 이메일 : abc@gmail.com
		con.setFaxNumber("123-456");
		System.out.println("팩스번호 : " + con.getFaxNumber()); // 팩스번호 : 123-456
	}
}

 

 

메소드 오버로딩

 

- 오버로딩 자체의 뜻은 무언가를 오버해서 로드한다 (많이 싣는다)는 느낌으로 받아들이자.

- 메소드 이름은 하나인데 매개변수 타입이나 개수, 순서 등을 달리하여 여러 개를 만드는 것이다.

- 예를 들어 매개변수의 타입이 다른 두 가지 오버로딩된 메소드는 호출이 된 경우 JVM이 매개값의 타입을 보고 알맞는 메소드를 선택한다.

 

- 메소드 오버로딩이라고 할 수 없는 예시 두 가지

 1) 매개변수의 이름만 다른 경우

 2) 리턴 타입만 다른 경우

 두 경우 모두 JVM이 메소드를 선택할 때 아무런 도움을 주지 못하기 때문에 메소드 오버로딩이라고 할 수 없음

 

아래 두 가지 메소드 선언은 메소드 오버로딩이 아니므로 컴파일 에러가 발생한다.

int plus(int x, int y) {}
double plus(int a, int b) {}

 

System.out.println() 메소드에 관하여..

 

- println() 메소드는 괄호안에 들어오는 매개값의 타입을 매우 다양하게 하여 여태 우리가 원하는 모든 타입을 출력해줄 수 있었다. 

- 사실 이는 메소드 오버로딩이 되서 가능했던 것이다.

- 아래 메소드 선언들은 전부 println() 메소드가 오버로딩된 것이다.

 

public class Println {
	//메소드
	void println() {}
	void println(int x) {}
	void println(long x) {}
	void println(float x) {}
	void println(double x) {}
	void println(boolean x) {}
	void println(char x) {}
	void println(String x) {}
	void println(int[] arr) {}
	void println(char[] arr) {}	
}

 

 

직사각형과 정사각형 넓이 계산 예제

 

public class Calculator_rectangle {
	//정사각형의 넓이
	double areaRectangle(double width) {
		return width * width;
	}
	
	// 직사각형의 넓이
	double areaRectangle(double width, double height) {
		return width * height;
	}
}

 

public class Calculator_rectangle_Example {
	public static void main(String[] args) {
		Calculator_rectangle myCalcu = new Calculator_rectangle();
		
		// 정사각형의 넓이 구하기
		double result1 = myCalcu.areaRectangle(10);
		
		// 직사각형의 넓이 구하기
		double result2 = myCalcu.areaRectangle(10,20);
		
		// 결과 출력
		System.out.println("정사각형 넓이 = " + result1); // 정사각형 넓이 = 100.0
		System.out.println("직사각형 넓이 = " + result2); // 직사각형 넓이 = 200.0
	}
}

 

 

main 메소드의 원리

 

[C++] 왜 int main()을 쓸까? (tistory.com)

 

[C++] 왜 int main()을 쓸까?

본격적인 알고리즘 준비에 앞서 이전부터 궁금했던것이 있어 찾아보기로 했다. 지금까지 습관적으로 쓰던 int main() 형식, 결론적으로는 0을 return하면 void를 쓰지 왜 int를 쓰나라는 의문을 항상

hezzong.tistory.com

 

반응형

댓글