조컴퓨터

200824 OOP 08 - Java Method, Overload, Main Method, Sort 본문

자바 웹개발자 과정/JAVA

200824 OOP 08 - Java Method, Overload, Main Method, Sort

챠오위 2020. 8. 27. 09:51

메소드 Method (★★★★)

함수, function, procedure

→ 일정한 기능을 가지고 있는 것

 

메소드는 객체의 동작에 해당하는 중괄호 { } 블록을 말한다. 중괄호 블록은 이름을 가지고 있는데, 이것이 메소드 이름이다. 메소드를 호출하게 되면 중괄호 블록에 있는 모든 코드들이 일괄적으로 실행된다. 메소드는 필드를 읽고 수정하는 역할도 하지만, 다른 객체를 생성해서 다양한 기능을 수행하기도 한다. 메소드는 객체 간의 데이터 전달의 수단으로 사용된다. 외부로부터 매개값을 받을 수도 있고, 실행 후 어떤 값을 리턴할 수도 있다.

 

 

메소드 형식

→ 형식) 리턴형 함수형( )

예시) 식별자 : 프로젝트명 basicJava

                 : 패키지명    oop0824

                 : 클래스명    Test01_method

                   변수명, 함수명

 

"test" : 문자열 상수

test    : 변수

test( ) : 함수

 

함수는

1) JAVA가 제공하는 함수,

2) 사용자의 필요에 의해 정의된(user defined) 함수

두 가지가 있다.

 

함수는 호출한 곳으로 되돌아가는 즉, 리턴하는 특징이 있다. 제일 마지막 줄의 리턴값은 생략하는 경우가 많다.

 

리턴 타입은 메소드가 실행 후 리턴하는 값의 타입을 말한다. 메소드는 리턴값이 있을 수도 있고 없을 수도 있다. 메소드가 실행 후 결과를 호출하는 곳에 넘겨줄 경우에는 리턴값이 있어야 한다.

 

 

 

public 리턴타입 메소드명 (매개변수) {객체의 동작}

 

함수 안에 함수를 선언할 수 없다.

 

 

 

메소드명

메소드명은 자바 식별자 규칙에 맞게 작성하면 된다.

 

1) 의미를 부여해야 한다.

2) 한글과 공백이 있으면 안 된다.

3) 숫자로 시작하면 안 된다. 

4) $와 _를 제외한 특수 문자를 사용하지 말아야 한다.

5) 관례적으로 메소드명은 소문자로 작성한다.

6) 서로 다른 단어가 혼합된 이름이라면 뒤이어 오는 단어의 첫머리 글자는 대문자로 작성한다.

 

다음은 잘 작성된 메소드 이름의 예시이다.

 

void run() {}
void startEngine() {}
String getName() {}
int[] getScores {}

 

 

함수를 작성할 때 고려사항

1) 매개 변수의 유무

    * 매개 변수 parameter :  메소드가 실행될 때 필요한 데이터를 외부로부터 받기 위해 사용된다.

2) 리턴값의 유무

3) 함수는 정의(작성)하고, 함수를 호출함으로써 수행된다.

 

 

다음은 위의 사항들을 고려한 코드이다.

 

1) 전달값(argument value)이 없는 경우

 

public class Test01_method {
	
	//메소드(멤버함수) 작성 영역
	
	//void 리턴값이 없다
	public static void test1() {
		System.out.println("JAVA");
	}//test1() end
	
	//리턴값이 있다
	public static void test2() {
		System.out.println("Python");
		//함수는 호출한 시점으로 돌아간다
		return; //마지막 return 명령어는 생략가능하다
	}//test2() end
	
	
	
	public static void main(String[] args) {
		
		//1)전달값(argument value)이 없는 경우
        
		test1();//함수호출
		test1();
		test1();//class 밑에 함수 있음
		
		test2();
		test1();
		test2();
		
	}//main() end
}//class end


/*
	JAVA
	JAVA
	JAVA
	Python
	JAVA
	Python
*/

 

2) 전달값이 있는 경우

 

public class Test01_method {
	
	//메소드(멤버함수) 작성 영역
	
	//매개 변수
	public static void test3(byte a) {
				//a는 매개 변수(parameter)
		System.out.println(a);
		return;//생략가능
	}//test3() end
		
	//여러 가지 매개 변수
	public static void test4(int a, int b, int c) {
				//매개변수는 개별적으로 선언한다
		System.out.println(a+b+c);
	}//test4() end
	
	//double형 매개 변수
	public static void test5(double a, double b) {//지역적 a
		System.out.println(a+b);
	}//test5() end
	
	//char형 매개 변수
	public static void test6(char ch, byte n) {
		for(int a=1; a<=n; a++) {
			System.out.print(ch);
		}//for end
	}//test6() end
	
	
	public static void main(String[] args) {
		
		//2)전달값이 있는 경우
		test3(10);//class 밑의 test3이 여기서 
		test3(20);
		test3(30);
		
		//전달값은 1개 이상 가능하다
		test4(7,8,9);//24=7+8+9
		test4(1,2,3);//6=1+2+3
		
		test5(1.2, 3.4);//4.6=1.2+3.4
		
		byte num=100;
		test6('#', num);//#기호 100번

	}//main() end
}//class end


/*
	10
	20
	30
	24
	6
	4.6
	#*100
*/

 

3) 리턴값이 있는 경우

 

public class Test02_method {
	
	public static int test1(int a, int b) {
		int sum=a+b;
		//return; 리턴값이 없다(void)
		return sum; //리턴값은 1개값만 리턴할 수 있다
			    //리턴값의 자료형을 void 자리에 쓴다
	}//test1() end
	
	public static String test2(int a) {
		if(a%2==0) {
			return "짝수";
		}else {
			return "홀수";
		}//if end
	}//test2() end
	
		
	public static void main(String[] args) {
    
		//3)리턴값이 있는 경우
		int result=test1(3, 5);
		System.out.println(result); 	//8
		System.out.println(test1(2, 4));//6
		
		String str=test2(7);//자료형 필수
		System.out.println(str);
		System.out.println(test2(10));
				
	}//main() end
}//class end

/*
	8
	6
	홀수
	짝수
*/

 

 

 

문제1) 윤년을 확인하는 함수

 

내 답안 

 

public class Test02_method {
	
	public static String test3(int y) {
		if(y%4==0 && y%100!=0 || y%400==0) {
			return "윤년";
		}else {
			return "평년";
		}//if end	
	}//test3() end


	public static void main(String[] args) {
    
		String year=test3(2020);
		System.out.println(year);
		
	}//main() end
}//class end

//윤년

 

test3( )함수에 if문. 이 문제의 구조는 '만약 ~하면 ~~다'가 어울리기 때문

if문에 윤년 공식. 이 공식이 성립하는 년도는 "윤년" 아니면 "평년"

 

따라서 Boolean형이 아니어도 풀이 가능

 

 

선생님 답안

 

public class Test02_method {
	
	public static boolean leap(int y) {
		if(y%4==0 && y%100!=0 || y%400==0) {
			return true;
		}else {
			return false;
		}//if end
	}//leap() end
	

	public static void main(String[] args) {
				
		if(leap(2020)) {
			System.out.println("윤년");
		}else {
			System.out.println("평년");
		}//if end
		
	}//main() end
}//class end

//윤년

 

Boolean형으로 풀이. 

leap( )함수에 if문. if문에 대한 사항은 내 풀이와 동일

Boolean형이기 때문에 true와 false로 출력

 

main( )함수에서 true의 경우 "윤년" 출력 아니면 "평년" 출력

 

 

 

문제2) 팩토리얼값을 구하는 함수

 

public class Test02_method {

	public static long fact(int f) {
		long gop=1;
		for(int a=f; a>=1; a--) {
			gop=gop*a;
		}//for end
		return gop;
	}//fact() end
	
	
	public static void main(String[] args) {
		
		long gop=fact(4);
		System.out.println(gop); //24=4*3*2*1
		
	}//main() end
}//class end

//24

 

main( )함수에서 long형으로 숫자를 받음

factorial에 대한 수식이기 때문에 fact(int f)로 설정

(이때 매개 변수 f 값은 위의 식이 길어져서 변수 f 로 설정하였음)

 

fact( )함수에서 gop=1을 미리 지정

이 값을 for문에 대입

for문은 main( )함수에서 받은 f 값인 4를 기준으로 범위 지정

factorial값은 구하고자 하는 숫자에서 1까지의 값을 곱하므로 

그 범위는 시작값 4, 종료값 1, -1씩 감소로 놓고 식을 구성

 

 

 

재귀적 함수 호출

→ 자신이 자신의 함수를 호출할 수 있다

 

다음과 같은 형태의 함수를 재귀적 함수라 한다.

 

public static void test() {
	test();
}//test() end

 

예를 들면,

 

public class Test03_method {
			
	public static long fact(int a) {
		if(a==0) {
			return 1;
		}else {
			return a*fact(a-1); //재귀함수
		}//if end
	}//fact() end

	public static void main(String[] args) {

		System.out.println(fact(3)); //6
				
	}//main() end
}//class end

 

위와 같이 fact(a-1)이 static fact( )를 소환하는 형태를 재귀적 함수 호출이라 한다.

 

 

 

4) 전달값이 배열인 경우

 

4-1) int형 배열

 

import java.util.Arrays;

public class Test04_method {
	
	public static void test1(int a, int b) {
		System.out.println(a);
		System.out.println(b);
	}//test1() end
	
	public static void test2(int[] a) {
		for(int i=0; i<a.length; i++) {
			System.out.print(a[i]);
		}//for end
	}//test2() end

	
	public static void main(String[] args) {
    
		//전달값이 배열인 경우
		int[] num= {10, 20, 30};
        
		//call by value 값에 의한 호출방식
		test1(num[0], num[2]);
		
		//call by reference 주소값에 의한 호출방식
        test2(num);
			
	}//main() end
}//class end

/*
	10
	30
	102030
*/

 

4-2) String형 배열

 

import java.util.Arrays;

public class Test04_method {
		
	public static void test3(String a, String b) {
		System.out.println(a);
		System.out.println(b);
	}//test3() end
	
	public static void test4(String[] a) {
		for(int i=0; i<a.length; i++) {
			System.out.print(a[i]+" ");
		}//for end		
	}//test4() end
	
	
	public static void main(String[] args) {
    
		//전달값이 배열인 경우
		String[] name= {"무궁화", "진달래", "개나리"};
		test3(name[0], name[2]);
		test4(name);
		
	}//main() end
}//class end

/*
	무궁화
	개나리
	무궁화 진달래 개나리 
*/

 

참고) 오름차순 정렬 

 

import java.util.Arrays;

public class Test04_method {
	public static void main(String[] args) {
		
		int[] lotto= {3, 7, 4, 28, 13, 15};
		
		//1차원 배열을 전달하면 오름차순으로 정리해 주는 기능
		Arrays.sort(lotto);//import java.util.Arrays; 살아있어야 성립
		
		for(int i=0; i<lotto.length; i++) {
			System.out.println(lotto[i]);
		}//for end
				
	}//main() end
}//class end

/*
	3
	4
	7
	13
	15
	28
*/

 

 

4-3) int형 2차 배열

 

import java.util.Arrays;

public class Test04_method {
	
	public static void test5(int a, int b) {
		System.out.println(a);
		System.out.println(b);
	}//test5() end
	
	public static void test6(int[][] su) {
		for(int i=0; i<su.length; i++) {
			int col=su[i].length;
			for(int j=0; j<col; j++) {
				System.out.print(su[i][j]+" ");
			}//for end
		}//for end
	}//test6() end
	
	
	public static void main(String[] args) {
		
		int[][] su= {
				{1, 3, 5}
				, {2, 4, 6}
		};//[2행][3열]
		
		test5(su[0][0], su[1][1]);
		test6(su);
				
	}//main() end
}//class end

/*
	1
	4
	1 3 5 2 4 6 
*/

 

 

 

메소드 오버로딩

함수 중복 정의 Method Overload

→ 함수명을 중복해서 사용할 수 있다

 

메소드 오버로딩의 전제조건

→ 매개 변수의 갯수가 달라야 한다

→ 매개 변수의 자료형이 달라야 한다

 

 

다음과 같은 형태를 메소드 오버로딩이라 한다.

 

public static void hap(int a, int b) {
	int result=a+b;
    return result;
}//hap() end

public static void hap(double a, double b) {
	int result=a+b;
    return result;
}//hap() end

 

왜 이런 방식의 함수를 지정하였나?

위의 hap( ) 함수에서 int형이 아니라 double형의 값을 계산하기 위해서 매개 변수가 double형으로 지정된 hap( ) 함수를 하나 더 선언한 것이다. (double형의 함수를 다시 지정하기 번거롭기 때문이다.)

 

hap(10.3, 2.2)

 

위와 같이 hap( ) 함수를 호출하면 hap(int a, int b)는 실행되지 않는 반면에 hap(double a, double b)는 실행된다.

 

 

예제) 메소드 오버로드

 

public class Test05_overload {
	
	public static void hap(int a) {	
		System.out.println(a);
	}//end
	
	public static void hap(int a, int b) {
		System.out.println(a+b);
	}//end
	
	public static void hap(double a) {
		System.out.println(a);
	}//end
	
	public static void hap(double a, double b) {
		System.out.println(a+b);
	}//end


	public static void main(String[] args) {
		
        //Method Overload
		hap(2);       //2
		hap(3, 5);    //8
		hap(5.6);     //5.6
		hap(7.8, 9.0);//16.8
		
		//절대값 구하기
		System.out.println(Math.abs(3));
		System.out.println(Math.abs(4L));
		System.out.println(Math.abs(5.6f));
		System.out.println(Math.abs(7.8d));
		//3		int형
		//4L	long형
		//5.6f 	float형
		//7.8d 	double형(d 접미사 생략 가능)
		
		System.out.println(Math.max(2, Math.max(4, 6))); //6
		
	}//main() end
}//class end

 

 

 

자바 클래스(.class) 실행 순서

재귀 함수는 자기 자신이 자신을 호출할 수 있는 함수라 하였다.

그렇다면 main( ) 함수도 재귀 함수 역할을 할 수 있지 않을까? 

 

아니다. main( ) 함수는 사용자가 임의로 호출할 수 없다.

 

자바 가상 머신 Java Virtual Machine(JVM)이 클래스를 실행할 때 main( ) 함수가 호출된다.

 

※ JVM은 좀 더 자세히 공부가 필요한 영역이다.

 

 

 

 

정렬 Sort

특정한 키(key field)를 기준으로 순서대로 재배치하는 것

 

 

정렬의 유형

1) 오름차순 ascending sort ASC

   예시) 1, 2, 3, ... , 10 / ㄱ, ㄴ, ㄷ, ... , ㅎ / A, B, C, ... , a, b, c, ... , z

 

2) 내림차순 descending sort DESC

   예시) 10, 9, 8, ... ,1 / Z, Y, X, ... , z, y, x, ... , a

 

 

* 정렬을 공부하는 이유?

DB에서 자료를 정렬해서 가져와야 하기 때문!

 

 

정렬의 방법

1) 삽입 정렬 insertion sort

   아직 정렬되지 않은 임의의 데이터를 이미 정렬된 부분의 적절한 위치에 삽입해 가며 정렬하는 방식

 

2) 선택 정렬 selection sort

   정렬되지 않은 데이터들에 대해 가장 작은 데이터를 찾아 가장 앞의 데이터와 교환해나가는 방식

 

 

예제) selection sort 알고리즘을 이용하여 오름차순으로 정렬 후 출력하시오

 

int[] num= {9,7,5,3,1};

for(int a=0; a<num.length-1; a++) {
	for(int b=a+1; b<num.length; b++) {
		if(num[a]>num[b]) {		//오름차순
			int tmp=num[b];
			num[b]=num[a];
			num[a]=tmp;
		}//swap
	}//for end
}//for end
		
for(int i=0; i<num.length; i++) {
	System.out.print(num[i]+"");	//13579
}//for end
		
System.out.println();

 

9 7 5 3 1
7 9 5 3 1
5 9 7 3 1
3 9 7 5 1
1 9 7 5 3
---------- step1 (첫 번째 줄 기준)
1 7 9 5 3
1 5 9 7 3
1 3 9 7 5
---------- step2 (두 번째 줄 기준)
1 3 7 9 5
1 3 5 9 7
---------- step3 (세 번째 줄 기준)
1 3 5 7 9
---------- step4 (네 번째 줄 기준)

 

위의 과정은 4회전만에 오름차순 정렬이 완료되었다.

 

 

3) 버블 정렬 bubble sort

   서로 이웃한 데이터들을 비교하며 가장 큰 데이터를 가장 뒤로 보내며 정렬하는 방식

 

 

예제) bubble sort 알고리즘을 이용하여 내림차순으로 정렬 후 출력하시오

 

for(int a=3; a>=0; a--) {
	for(int b=0; b<=a; b++) {
		if(num[b]<num[b+1]) { //내림차순
			int tmp=num[b+1];
			num[b+1]=num[b];
			num[b]=tmp;
		}//swap
	}//for end
}//for end
		
for(int i=0; i<num.length; i++) {
	System.out.print(num[i]+"");	//97531
}//for end

 

9 7 5 3 1
7 9 5 3 1
7 5 9 3 1
7 5 3 9 1
7 5 3 1 9 
--------- step1
5 7 3 1 9
5 3 7 1 9
5 3 1 7 9
--------- step2
3 5 1 7 9
3 1 5 7 9
--------- step3
1 3 5 7 9
--------- step4

 

위의 과정은 4회전만에 오름차순 정렬이 완료되었다.

 

 

 

 

과제) 표준편차를 구하시오

 

다음 사항을 표준편차라 가정하고 풀자.

 

/*
	aver의 평균(87.2)을 구하고
	85-87.2 -> -2.2 //4.84
	90-87.2 -> 2.8	//7.84
	93-87.2 -> 5.8	//33.64
	86-87.2 -> -1.2	//1.44
	82-87.2 -> -5.2	//27.04
			
	평균(87.2)과 차이값을 전부 양수로 바꾼다
	-> 편차
	2.2
	2.8
	5.8
	1.2
	5.2
			
	표준편차 : 편차의 평균값//3.44
*/

 

내 답안

 

public class Test08_homework {
	
	public static double sd(double[] aver) {
		double sum=0.0;
		double avg=0.0;
		double result=0.0;
		
		for(int i=0; i<aver.length; i++) {
			sum=sum+aver[i];
		}//for end
        
		avg=sum/aver.length;
		sum=0;
		
		for(int i=0; i<aver.length; i++) {
			if(aver[i]-avg<0) { //주어진 값-평균
				sum=sum+Math.abs(aver[i]-avg);
			}else {
				sum=sum+(aver[i]-avg);
			}//if end
		}//for end
        
		result=sum/aver.length;
		return result;
        
	}//sd() end
	
	
	public static void main(String[] args) {
		//표준편차 구하기
		
		int[] aver= {85, 90, 93, 86, 82};
		double result=sd(aver);
		System.out.println(result);	//3.4400000000000004
		
	}//main() end
}//class end

 

sum, avg, result를 먼저 double형으로 지정

sum은 입력된 값의 전체 합. 배열으로 입력되었기 때문에 for문으로 식 작성

sum에 대한 평균인 avg를 구함 (aver.length는 입력된 배열의 길이)

 

이때 앞서 사용하였던 용도의 sum이 아닌 새로운 용도로 sum을 사용하기 위해 sum=0;

새로운 용도의 sum은 표준편차를 계산하기 위한 용도의 sum

즉, (주어진 값) - (평균값) 을 각각 구한 후 절대값을 씌워줌. 이에 대한 전체 합 sum

 

if문을 이용하여 절대값을 씌워줄 범위를 나누어 줌

→ aver[i]-avg<0 / aver[i]-avg>=0 

이 값에 절대값을 씌우고 sum 누적

(여기서 if문으로 나누지 않고 그냥 Math.abs로 계산해도 될 듯)

 

누적된 sum을 배열 길이로 나누어 주면 그 값이 선생님이 정의한 표준편차

(이때의 표준편차는 식을 쉽게 하기 위해 정의를 달리함. 오해 ㄴㄴ)

 

 

 

수학에서 정의한 표준편차로 풀이한 내 답안

 

public class Test08_homework {
	
	public static double sd(double[] aver) {
		double sum=0.0;
		double avg=0.0;
		double result=0.0;
		
		for(int i=0; i<aver.length; i++) {
			sum=sum+aver[i];
		}//for end
        
		avg=sum/aver.length;
		sum=0;
		
		for(int i=0; i<aver.length; i++) {
			sum+=(aver[i]-avg)*(aver[i]-avg);//분산값
		}//for end
        
		result=Math.sqrt(sum/aver.length);
		return result;
		
	}//sd() end
	
	
	public static void main(String[] args) {
		//표준편차 구하기
		
		int[] aver= {85, 90, 93, 86, 82};
		double result=sd(aver);
		System.out.println(result);	//3.867815921162743

	}//main() end
}//class end

 

위의 풀이에 수학적 표준편차를 끼얹음

 

 

 

선생님 답안

 

public class Test08_homework {
	
	public static double sd(int[] aver) { //double[] aver
		int size=aver.length; //5
		
		//aver의 총합계 구하기
		double hap=0.0;
		double result=0.0;
		for(int i=0; i<size; i++) {
			hap=hap+aver[i];
		}//for end
		
		//aver의 평균값
		double avg=hap/size;
		hap=0;
		
		for(int i=0; i<size; i++) {
			//aver 각 요소와 평균(avg)과의 차이값(편차)를 구하고
			//양수로 바꾸기
			double d=Math.abs(aver[i]-avg);
			hap=hap+d;
		}//for end
		result=hap/size;
		return result;
		
	}//sd() end
	
	
	public static void main(String[] args) {
		//표준편차 구하기
		
		int[] aver= {85, 90, 93, 86, 82}; //int
		double result=sd(aver);
		System.out.println(result);	//3.4400000000000004

	}//main() end
}//class end

 

int형 배열의 형태로 값을 입력

sd( ) 함수를 호출

 

배열의 길이를 구하여 size에 대입한 후 

hap, result를 double형으로 지정

hap은 입력된 값의 전체 합이므로 for문을 통해 계산

 

avg를 double형으로 지정

avg는 앞서 구한 hap을 size로 나누어 준 값

hap=0 재설정

 

for문을 통해 aver[i]-avg 계산 후 절댓값을 씌워 준 후 전체 합 hap 계산

이 값을 size로 나누어 준 값이 표준편차