재밌고 어려운 IT를 이해해보자~!
함수(Function) 본문
함수(Function)
프로그래밍에서 함수의 개념은 수학에서 나오는 함수의 개념과 동일하다.
예를들어 f(x) = 5x + 1 이라면 x에 3을 대입했을때 16이라는 결과를 얻는다.
이처럼 자바의 함수도 마찬가지이다.
함수란 하나의 기능을 수행하는 일련의 코드로써 호출하여 사용 및 함수가 실행된 후 값을 반환할 수 있다. 함수가 선언되면 여러 곳에서 호출되어 사용될 수 있다.
함수,메서드 : output
함수명(input) → 메서드 시그니처
메서드 시그니처란 메서드이름과 매개변수리스트의 조합을 의미한다.
메서드를 만들기전에 항상 메서드 시그니처 생각해야한다.. 그 이유는 나중에 설명할 오버로딩 때문이다.
또한 문제의 뉘앙스를 잘 파악해야한다.
함수의 3요소는
1. input (매개변수,args,인자,인수,파라미터,입력값)
2. output (return,반환값,결과값,출력값)
3. 기능 -> 해당 함수의 기능을 유추할수있는 이름으로 함수명을 작성
함수의 4유형은 다음과 같이 정리할 수 있다.
1. Input X output X
2. input O output X
3. input X output O
4. input O output O
함수의 장점은 무지하게 많다.
코드를 재사용
가독성 좋아짐
개발시간 단축 !
개발비용 절감 !
오류의 파급효과 줄어듦
성능향상에 유리
-> 반복문, 함수를 잘 사용하고 이해하는 사람이 인재다. 따라서 잘 이해하도록 합자!
각각 떄와 상황에 따라서 함수를 작성하면 된다.
* main() 도 합수입니다.
함수이 선언은 class 내부 그리고 main() 바깥쪽에 선언하고.
main()에서 호출하여 사용한다.
다음 코드를 보자!
package class03;
public class Test01 {
// input X output O
// JAVA에서는 output 모든 타입이 가능하지만,
// 단 1개만 반환할수있음 !
public static int funcA() {
System.out.println("funcA()는 5를 반환하는 함수입니다.");
return 5;
}
public static void main(String[] args) {
funcA();
System.out.println(funcA());
// Run-> main, print 수행해야하는 함수 2개임
// -> funA() -> println()
// 8-> 16-> 19-> 23->24
int num = funcA();
System.out.println("funcA()의");
}
}
이코드에서 System.out.println(funcA()); 부분을 보면
println안에있는 funcA() 함수가 먼저 실행되고 그뒤에 println() 함수가 실행된다.
따라서 출력은 funcA() 안에있는 print문 "funcA()는 5를 반환하는 함수입니다."가 출력되고,
그이후엔 메인에 있는 프린트문 println(funA()) 가 출력되는데 이때 funA()의 return값이 5 이기 때문에 5를 출력해준다.
함수 관련 문제 3개 풀이!
package class03;
import java.util.Random;
import java.util.Scanner;
public class Test04 {
// 문제1) funcA() 함수가 있습니다.
// 정수를 3개 랜덤으로 생성합니다.
// 랜덤 범위는 1~6
// 3개의 랜덤 정수를 모두 Console에 출력해주세요.
// 그리고 가장 큰 랜덤 정수를 Console에 출력해주세요.
public static void funcA() {
// 1유형
Random rand = new Random();
int[] arr = new int[3];
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(5) + 1;
}
System.out.print("랜덤 정수는 :");
for (int datas : arr) {
System.out.print(datas + " ");
}
System.out.print("최대값은 :");
int max = arr[0] > arr[1] ? (arr[0] > arr[2] ? arr[0] : arr[2]) : (arr[1] > arr[2] ? arr[1] : arr[2]);
System.out.println(max);
}
// 문제2) funcB() 함수가 있습니다.
// 사용자에게 정수 2개를 입력받습니다.
// 입력받은 2개의 정수 합을 main()함수로 반환해주세요.
// 함수의 재사용성 용의함 !!2번
public static int funcB() {
// 사용자에게 입력받는다!!!!!
Scanner sc = new Scanner(System.in);
System.out.println("더할 숫자 2개 입력하세요!!");
int a = sc.nextInt();
int b = sc.nextInt();
int total = a + b;
return total;
}
// 문제3) funcC() 함수가 있습니다.
// main()함수에서 사용자에게 입력받은 2개의 정수들을
// 매개변수로 받아와서
// 두개의 정수중 더 작은 값을 Console에 출력해주세요.
// 이후 main()함수로 더 작은 값을 반환해주세요.
public static int funcC(int a, int b) {
int c = a < b ? a : b;
System.out.println("더작은값은 :" + c);
return c;
}
public static void main(String[] args) {
funcA();
System.out.println();
System.out.println(funcB());
int num = funcB();
System.out.println(num);
System.out.println();
Scanner sc = new Scanner(System.in);
System.out.println("비교할 숫자를 2개 입력하세요");
int a = sc.nextInt();
int b = sc.nextInt();
funcC(a, b);
}
}
메서드 시그니처를 잘 활용한 오버로딩 코드
package class07;
public class Test01 {
// 1번 함수
// 정수 3개를 인자로 받아와서,
// 3개를 각각 +1씩 하고
// 3개의 정수의 총합을 Console에 출력하는 함수
// 2번 함수
// 정수배열 1개를 인자로 받아와서.
// 배열의 모든 요소를 각각 +1씩 하고
// 배열의 모든 요소의 총합을 Console에 출력하는 함수
public static void printTotal(int a, int b, int c) {
a++;
b += 1;
c = c + 1;
int total = a + b + c;
System.out.println("funcA() 총합= " + total);
}
// 2번 함수
// 정수배열 1개를 인자로 받아와서, -> input
// 배열의 모든 요소를 각각 +1씩 하고
// 배열의 모든 요소의 총합을 Console에 출력하는 함수 -> output
public static void printTotal(int[] datas) {
for (int i = 0; i < datas.length; i++) {
datas[i]++;
}
int total = 0;
for (int data : datas) {
total += data;
}
System.out.println("funcB() 총합=" + total);
}
public static void main(String[] args) {
int a = 10, b = 20, c = 30;
printTotal(a, b, c); // 값에 의한 호출
// 변수 a,b,c에 대한 정보가 전달 XXX
System.out.println("main()의 현재 a,b,c값을 출력");
System.out.println("a= " + a);
System.out.println("b= " + b);
System.out.println("c= " + c);
int arr[] = new int[5];
for (int i = 0; i < arr.length; i++) {
arr[i] = 10;
}
// [ 10 10 10 10 10 ]
printTotal(arr); // 참조에 의한 호출(call by reference)
// heap(힙) 메모리 영역의 주소값이 전달 O
// 실제 메모리에 접근가능함!!!!!
System.out.println("main()의 현재 numArr 상태를 출력");
for (int num : arr) {
System.out.print(num + " ");
}
// 결론★ 함수 호출 방식에는 크게 2가지가 있는데,
// 1)값에 의한 호출(call by value)
// 원시 타입 데이터가 인자일때
// int,double,String,boolean..a.
// 2) 참조에 의한 호출(call by reference)
// new 연산자를 사용하여 만든 변수가 인자일때
// int[], 배열, 객체,.a..a
// 참조에 의한 호출은 heap 메모리의 주소값을 보내는것 떄문에 발생하므로
// 원본 손실될 수 있음 주의!!!!!!!!!!!
//void func(int a, int[] b) --> a는 값에의한 호출 b는 참조에 의한 호출
//★★★★★오버로딩★★★★기능
//Java는 함수명 중복사용을 허용
// 단,
// input과 output이 서로 달라야하고,
// 기능이 같아야합니다!
// ★★★오버라이딩이나온다 나중에★★★
//JAVA에서 input(or output)을 보고 알아서 판단해서 호출합니다!~~
}
}
위 코드에서 알아야 할 중요한 부분
1. 오버로딩!
한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을 '메서드 오버로딩' 또는 간단히 '오버로딩'이라 한다.
- 메서드 이름이 같아야한다.
- 매개변수의 개수 또는 타입이 달라야 한다.
-input output이 서로 달라야한다.
즉 메서드 시그니처를 신경써줘야한다.
2. 호출 방식
1) 값에 의한 호출(call by value)
원시 타입 데이터가 인자일때
int,double,String,boolean..a.
2) 참조에 의한 호출(call by reference)
new 연산자를 사용하여 만든 변수가 인자일때
int[], 배열, 객체 a
참조에 의한 호출은 heap 메모리의 주소값을 보내는것 떄문에 실제 메모리에
접근가능하므로 원본 손실될 수 있음 주의!!
나중에 나올 오버라이딩 찍먹
메소드 오버라이딩(method overriding) ?
방금 배운 오버로딩(overloading)이란 서로 다른 시그니처를 갖는 여러 메소드를 하나의 이름으로 정의하는 것이었다.
오버라이딩(overriding)이란 상속 관계에 있는 부모 클래스에서 이미 정의된 메소드를 자식 클래스에서 같은 시그니쳐를 갖는 메소드로 다시 정의하는 것이라고 할 수 있다.
자바에서 자식 클래스는 부모 클래스의 private 멤버를 제외한 모든 메소드를 상속받는다..
이렇게 상속받은 메소드는 그대로 사용해도 되고, 필요한 동작을 위해 재정의하여 사용할 수도 있다.
즉, 메소드 오버라이딩이란 상속받은 부모 클래스의 메소드를 재정의하여 사용하는 것을 의미한다.
상속받은 부모클래스의 메소드를 쓰게 편하게 바꿔서 사용하는 것 이다!
다음 코드의 출력값을 실행시키지 않고 생각해보자.
package class07;
public class Test02 {
public static void funcA(int a, int b) {
System.out.println("[1]");
double c = a * 1.0;
funcA(c, c);
}
public static void funcA(int a, double b) {
System.out.println("[2]");
double result = a + b;
System.out.println(a + " + " + b + " = " + result);
}
public static void funcA(double a, double b) {
System.out.println("[3]");
double result = a - b;
System.out.println(result);
}
public static int funcB(int num) {
System.out.println("[4]");
return num * 10;
}
public static int funcC(int[] datas) {
System.out.println("[5]");
datas[datas.length - 1] = -2;
return datas.length;
}
public static void main(String[] args) {
int[] numArr = new int[5];
for (int i = 0; i < numArr.length; i++) {
numArr[i] = (i + 1) * 10;
}
System.out.println("결과는 " + funcC(numArr));
for (int num : numArr) {
System.out.print(num + " ");
}
System.out.println();
int num = 1;
num = funcB(num);
System.out.println("num= " + num);
int a = 17;
int b = 18;
double c = 3.14;
funcA(a, b);
funcA(b, c);
funcA(c, b);
System.out.println("a= " + a);
System.out.println("b= " + b);
System.out.println("c= " + c);
}
}
상위 코드 디버깅표
왼쪽 : 실제 출력 값
오른쪽 :예상값
[5] 출력후 줄바꿈!
0은 double자료형이라서 0.0으로 출력
funcA(int a, int b) 에서
a + b 를 double변수 result 에 대입할때 형변환이 되지않고 자료형 그대로 더해진다.
18 + 3.14 = 21.14
'코리아IT핀테크과정' 카테고리의 다른 글
함수를 활용한 학생부 프로그램 리팩토링(Refactoring) (2) | 2023.11.28 |
---|---|
삽입정렬 코드 실행 (0) | 2023.11.28 |
버블정렬 코드 개선 (0) | 2023.11.27 |
이진 탐색(Binary Search) (2) | 2023.11.26 |
학생부 프로그램 제작 (2) | 2023.11.25 |