Chatper 1: 메소드
- 메소드 선언
- 메소드 호출
- return statement
- 지역 변수
- 값 return
Chapter 2: 파라미터(Parameter)
- 파라미터 선언과 호출
- 파라미터 전달 매커니즘
- Pass by Value, Pass by Reference
- 가변 길이 목록 파라미터 사용
- 재귀 메소드 사용
Chapter 3: 메소드 오버로딩(Method Overloading)
- 메소드 오버로딩 정의
- 메소드 시그니처
- 오버로드된 메소드 사용
Lab 5-2 메소드 오버로딩
Chatper 1: 메소드
Function(함수): 특정 값을 넣으면 반드시 계산 결과의 값을 반환.
Procedure(프로시저): 값을 반환하지 않고 절차만을 수행.
(C 이후의 언어들은 2가지의 경계가 모호해져서 return이 있어야 함수인데 void를 사용해서 반환값이 없어도 된다)
Method(메소드): Java에서 함수를 사용하려면, 클래스 아래에 선언된 함수를 해당 클래스의 객체를 생성해서 사용해야 한다. 이 동작(행위)를 method라고 한다. 따라서 객체지향언어에서 메소드는 함수와 프로시저의 총칭이다.
* 객체지향 언어: 객체를 만들어서 객체 간 상호작용을 통해 문제를 해결하고 값을 산출하는 언어이다.
Static binding(정적 바인딩): 컴파일 시점에 호출이 결정. (실행 이전에 값이 확정)
Dynamic binding(동적 바인딩): 런타임 시점에 호출이 결정. (실행 이후에 값이 확정)
메소드 선언
- 메소드
- 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것.
- 함수, 서브루틴, 프로시저, 서브 프로그램과 비슷한 개념.
- main 메소드: Java 응용 프로그램의 진입점(Application Entry Point)
- 메소드 형식
- public [static] int MethodName() { }
- public: Access Modifier, [static]: Binding Type, int: Return_type
public class MyClass {
static void myMethod() {
System.out.println("Example method");
}
public static void main(String[] args) {
System.out.println("main method");
}
}
메소드 호출
- 같은 클래스 내에서 메소드 호출. ex) myMethod();
- 다른 클래스에 있는 메소드 호출. ex) OtherClassName.methodInOtherClass();
- 중첩 호출: 메소드 내에서 메소드를 호출할 수 있다.
public class Sample {
public static int add(int i, int j) {
return i+j;
}
public static void main(String[] args) {
add(1,2); // add는 static이기 때문에 이렇게 사용이 가능하다
// 만약 add라는 static이 Sample2에도 같이 선언되어 있다면,
// 같은 클래스 내에 있는 add 메소드를 호출한다.
// dynamic 메서드(static)을 안쓰면 이렇게 호출해야함
// Sample s = new Sample();
// s.add(1,2);
}
}
class Sample2 {
private static int add(int i, int j) {
return Sample.add(i, Sample.add(1,2));
// 호출자 입장에서는 메소드는 return 타입으로 보인다 add는 int로 보임
}
}
return statement
- return: "귀환", "반환".
- return문을 만나면 메소드는 즉시 종료된다.
- 조건문에서 return 할 수 있다. (그냥 쓰면 unreachable statement 오류가 발생하기 때문이다)
- 메소드 종료: return / 메소드 내 모든 statement가 실행.
/* i가 10보다 작을 경우 즉시 return */
static void method1() {
int i = 10;
System.out.println("Hello");
if (i < 10)
return;
System.out.println("World!");
}
실행결과
/* i<10 경우 */
Hello
/* i>=10 경우 */
Hello
World!
지역 변수 (Local Variable)
- 메소드가 시작할 때 생성.
- 메소드 내에서만 유효.
- 메소드 종료시(return / 모든 statement 실행) 제거.
전역 변수 (클래스 내 공유 변수)
- 클래스 레벨에서 선언된 변수로 클래스 내 모든 메소드에서 공유된다.
/* 공유 변수 count */
public class MethodCall {
static int count = 0;
static void myMethod() {
++count;
System.out.printf("메소드가 %d 번 호출되었습니다.\n", count);
}
public static void main(String[] args) {
myMethod();
myMethod();
}
}
값 return
- return type이 void인 메소드: 값을 반환하지 않는다. ex) return;
- return type이 void가 아닌 메소드: return type을 반환한다. ex) return sum;
- Call Stack (콜 스택): 프로그램 실행 중에 함수(메소드)의 호출을 추적하고 관리하는 메모리 구조.
public class test {
static int add(int i, int j) {
int sum;
sum = i+j;
return sum;
}
public static void main(String[] args) {
add(1,2);
}
}
Chapter 2: 파라미터
메소드 정의 ex) methodName(int i, int j) : format parameter / parameter 라 부른다.
메소드 실행 ex) methodName(1, 2): actual parameter / argument 라 부른다.
파라미터 선언과 호출
- 파라미터를 사용하면 정보를 메소드 안으로 전달하고 밖으로 반환할 수 있다.
- 파라미터 선언: 메소드 이름 뒤 괄호( )에 선언.
- 파라미터에 argument 전달: 메소드를 호출하여 파라미터에 argument를 전달. (Type이 같아야함)
static void defineParametersIntoMethod(int n, string s) {
...
}
defineParametersIntoMethod(1, “Hello, World!”)
파라미터 전달 매커니즘
- Pass by Value
- 값을 복사해서 전달.
- 값을 수정해도 원본 데이터에는 영향을 미치지 않음.
- Pass by Reference
- 주소 값을 전달 - 실제 값이 있는 위치를 전달.
- 값을 수정하면 원본 데이터의 값에 영향을 미침.
- Java는 모든 파라미터 전달에 Pass by Value를 사용.
Pass by Value
- 파라미터를 전달하는 기본 메커니즘
- 파라미터에 인자의 값이 복사됨.
- 메소드 내부에서 변수 값을 변경 가능.
- 메소드 내부에서 변경된 변수 값은 메소드 밖으로 영향을 주지 않음.
- 파라미터는 반드시 같은 타입이거나, 호환되는 타입이어야 한다.
static void addOne(int i) {
i++;
}
public static void main(String[] args) {
int j = 5;
addOne(j);
System.out.println(j); // 6이 아닌 5가 출력됨
}
가변 길이 목록 파라미터 사용
- 파라미터에서 타입 뒤에 ...을 사용, 메소드에 하나만을 사용할 수 있다.
- 같은 타입의 파라미터 여러 개를 배열로 변환하여 전달.
- 다른 타입의 파라미터와 함께 쓸 경우, 파라미터 목록의 제일 마지막에 선언.
ex) exampleMethod(String s, int... numbers)
public static int sumOfParameters(int... values) { // values는 int 타입의 여러 값을 받을 수 있다.
int sum = 0;
System.out.println("Count of parameters: " + values.length);
for (int i: values) {
i++;
sum += i;
}
return sum;
}
/* 가변길이 파라미터를 사용하는 두 가지 방법, 똑같이 동작한다 */
public static void main(String[] args) {
int result;
/* values에 int 타입 여러개를 배열로 변환하여 전달한다. */
result = sumOfParameters(1,2,3); // 콤마(,)로 구분된 요소들의 목록
result = sumOfParameters(new int[] {1,2,3}); // 배열
}
* 중요
- Java에서는 값이 무조건 pass by value로 넘어간다.
- Java에서 배열과 객체는 힙(Heap)영역에 동적으로 할당된다. 따라서 스택 영역에는 이것들의 값이 저장되어 있는 힙 영역의 주소가 들어있다. 이걸 pass by value 하게 되면 마치 pass by reference와 같은 결과가 나온다.
- Java에서 스택(Stack)영역에는 메소드 호출 시 생성되는 프레임(지역 변수, 매개 변수, 반환 주소 등)이 저장된다.
재귀(Recursive) 메소드 사용
Java의 메소드는 상호 재귀적이다. 메소드 A가 메소드 B를 호출할 수 있고, 메소
- 자기 자신(메소드)을 호출
- 직접적 호출
- 간접적 호출
- 대표적인 알고리즘 문제: 피보나치 수열, 하노이 탑, factorial
/* 재귀 메소드 예시: Factorial 문제 */
static int factorial (int n) {
if (n < 1) { // 재귀 메소드는 추가 호출없이 return하는 종료 조건이 있어야 한다.
return 1;
}
else {
return n * factorial(n - 1);
}
}
// 재귀 메소드
public class Algorithm {
public static int addNto10(int n) {
int result = 0;
for (int i=0; i<= 10; i++) {
result += i;
}
return result;
}
public static int addNtoNRecur(int n) {
if (n>10) {
return 0; // int를 return 해야하니까 0
}
else {
return addNtoNRecur(n+1) + n;
}
}
public static void main(String[] args) {
System.out.println(addNto10(1));
System.out.println(addNtoNRecur(1));
}
}
Chapter 3: 메소드 오버로딩(Method Overloading)
메소드 오버로딩 정의
- Class 내에서 같은 이름을 사용하는 메소드.
- 파라미터의 개수와 타입을 검사하여 구분.
- Java에서 다형성을 표현하는 한 가지 방법.
(메소드 오버로딩: 정적 바인딩, 메소드 오버라이딩: 동적 바인딩)
static int add(int i, int j) {
return i + j;
}
static int add(int i, int j, int k) {
return i + j + k;
}
public static void main(String[] args) {
int i = add(1, 2);
int j = add(1, 2, 3);
System.out.println(i + j);
}
메소드 시그니처
- 시그니처
- 컴파일러가 클래스의 메소드를 구분하는데 사용.
- 메소드 이름, 파라미터의 타입, 파라미터의 개수로 구성. ex) doSomething( int n )
- 파라미터의 이름, 메소드의 return type은 시그니처에 영향을 미치지 않음.
/* 시그니처가 다른 3개의 메소드 */
static int doSomething() {
}
static int doSomething(int n) {
}
static int doSomething(int n, int p) {
}
/* 오류: 메소드 시그니처는 return type을 포함 X */
static int doSomething (int n) {
}
static String doSomething (int n) {
}
/* 오류: 메소드 시그니처는 파라미터 이름을 포함 X */
static int doSomething (int n) {
}
static int doSomething (int j) {
}
오버로드된 메소드 사용
- 다른 파라미터가 필요한 유사한 메소드
- 기존 코드에 새 기능 추가: 기존 코드를 광범위하게 변경하지 않고 새 기능 추가.
Lab 5-2 메소드 오버로딩
class-programming_with_java/Module 05 메소드와 파라미터/contents/19_lab_5-2.adoc at master · gikpreet/class-programming
Contribute to gikpreet/class-programming_with_java development by creating an account on GitHub.
github.com
/* Multipler.java */
public class Multiplier {
public int apply(int left, int right) {
return left * right;
}
}
/* Adder.java */
class Adder {
public int apply(int right, int left) {
return right + left;
}
}
/* Algorithm.java */
public class Algorithm {
static final int addFrom1to10 = 55;
public static int sigma(int start, int end, int step) {
return accumulate(new Adder(), 0, start, end, step);
}
public static int pi(int start, int end, int step) {
return accumulate(new Multiplier(), 1, start, end, step);
}
public static int accumulate(Adder binder, int init, int start, int end, int step) {
int result = init;
for(int i=start; i<=end; i+=step) {
result = binder.apply(result, i);
}
return result;
}
public static int accumulate(Multiplier binder, int init, int start, int end, int step) {
int result = init;
for(int i=start; i<=end; i+=step) {
result = binder.apply(result, i);
}
return result;
}
public static void main(String[] args) {
System.out.println(sigma(1,10,1));
System.out.println(pi(1,10,1));
// 객체 생성은 Adder a = new Adder();인데 Adder a는 파라미터로, new Adder()는 인자로 쓴거다.
// 함수를 호출해서 argument -> parameter로 보내는 거니까.
System.out.println(accumulate(new Adder(), 0, 1, 10, 1));
System.out.println(accumulate(new Multiplier(), 1, 1, 10, 1));
}
}
실행 결과
55
3628800
55
3628800
[코딩 문제] Palindrom
2024.08.23 - [코딩 문제] - Palindrom
Palindrom
lightningtech.tistory.com
[코딩 문제] Anagram
2024.08.23 - [코딩 문제] - Anagram
Anagram
lightningtech.tistory.com
출처: https://github.com/gikpreet/class-programming_with_java/tree/master
GitHub - gikpreet/class-programming_with_java
Contribute to gikpreet/class-programming_with_java development by creating an account on GitHub.
github.com
'Java' 카테고리의 다른 글
[Java] 06. 배열 (0) | 2024.08.25 |
---|---|
[Java] 배열의 출력, 비교, 복사, 정렬 (0) | 2024.08.25 |
[OOP] 객체지향 설계 원칙: SOLID (0) | 2024.08.23 |
[OOP] 객체 지향 프로그래밍(OOP)의 정의와 4가지 특징 * (0) | 2024.08.23 |
[Java] 04. Statement와 Expression (0) | 2024.08.22 |