package javajungsuk6_10;

public class Ch06_17a19 {

    public static void main(String[] args) {
        // 6-17 ~ 6-19 메서드 호출

        // 입력값을 받는 '메서드 이름(매개변수(parameter): 작업에 필요한 값)'으로 호출한다.
        // 입력값이 필요하지 않는 메서드는 'void 메서드이름();'으로 호출한다.

        MyMath mm = new MyMath(); // 객체 생성
        long result = mm.add(6, 10); // 참조변수를 써주는 것은 중요하다. 작업결과를 저장할 변수를 만들어 줘야 메서드 사용이 가능하다.
        
        System.out.println(result);
        System.out.println("포인트1 : 매개변수도 long이어야 맞지만, int값을 넣어도 에러가 나지 않는다. long이 더 크기 때문에 자동형변환을 해준다.");
        System.out.println("포인트2 : 작업을 마치면 호출한 곳으로 돌아온다. mm.add(6, 10)가 계산이 되고 변수result에 저장이 된다.");
        System.out.println("포인트3 : 메서드는 클래스 영역에서만 정의가 가능하다.");


    } // main의 끝
}

class MyMath{
    long add(long a, long b){

        return a + b; // 입력값을 받는 함수
    }
}

package javajungsuk6_10;

public class Ch06_20a21 {

    public static void main(String[] args) {
        // 6-20 ~ 6-21 return문, 반환값

        // return문 : 실행 중인 메서드를 종료하고 호출한 곳으로 되돌아간다.
        // 반환 타입이 void(입력값을 받지 않는)가 아닌 경우는 return이 반드시 필요하다. / 생략불가

        Void v = new Void();

        v.Gugudan(3);
    } // main의 끝
}

class Void {
    void Gugudan(int dan){
        if(!(2 <= dan && dan <= 9)){
            return; // 입력받은 dan(단)이 2~9가 아니라면 메서드를 종료하고 호출한 곳으로 되돌아가기
        } // if의 끝

        for(int i = 0; i <= 9; i++){
            System.out.printf("%d * %d = %d%n", dan , i , dan * i);
        }

    } // Gugudan의 끝

    int multiply(int a, int b){
        return a * b;
    }

    int max (int a, int b){
        if(a > b){
            return a;
        }
        else {
            return b;
        } // else를 써주지 않으면 return이 없다고 에러가 난다. 왜냐하면 참일 때에는 return문이 있지만 거짓일 때에는 없기때문에 써줘야한다.

    }
} // class의 끝

package javajungsuk6_10;

public class Ch06_22 {

    public static void main(String[] args) {
        // 6-22 호출스택

        // stak : 밑이 막힌 상자라고 생각하면 된다. 차곡차곡 쌓인다. / 메서드 수행에 필요한 메모리가 제공되는 공간이다. / 호출되면 메모리에 할당
        // 박스에 책을 쌓는 과정과 다시 꺼내는 과정을 생각하면 쉽다. / 중간에 끼워넣거나 맨 아래에 있는 것을 꺼내는 것은 불가능하다.

        // 1번 main / 2번 println
        System.out.println("호출스택 과정");
        System.out.println("처음에는 비어있다.");
        System.out.println("프로그램의 시작인 main이 스택에 올라가고 실행이 된다.");
        System.out.println("println 호출, main위에 쌓이고 실행이 된다. main은 대기 상태가 된다.");
        System.out.println("println의 작업을 마치면 println이 제거되면서 main만 남게 된다.");
        System.out.println("더이상 실행될 것이 없으니 main도 스택에서 제거되고 스택에는 아무것도 남지 않고 끝난다."); // 프로그램 종료

    }
}

package javajungsuk6_10;

public class Ch06_23 {
    
    public static void main(String[] args) {
        // 6-23 기본형 매개변수

        // flash 동영상 참고
        // 이번 강의하고 다음 강의 굉장히 중요하다! 2개 다 보고 비교해가면서 여러번 다시 보기 / 예제 그림그리는 연습
        System.out.println("기본형 매개변수 : 변수의 값을 읽기만 하고 변경은 할 수 없다.");
        
        Data d = new Data(); //객체 생성
        d.x = 10; // 참조변수 d가 가리키는 x객체에 10을 넣겠다.
        System.out.println("main : " + d.x);

        Data.change(d.x); // change 메서드 호출
        System.out.println("After change(d.x)");
        System.out.println("main : " + d.x);

    } // main의 끝
}

class Data {
    int x;

    static void change (int x) { // static이기때문에 자동으로 객체생성을 해준다.
        x = 1000; // change메서드 안에 있는 x변수는 지역변수다. d.x와 다른 x이다.
        System.out.println("change x : " + x); // 지역변수 x는 1000이 출력된다.
    }
}

package javajungsuk6_10;

public class Ch06_24a25 {
    
    public static void main(String[] args) {
        // 6-24 ~ 6-25 참조형 매개변수, 참조형 반환타입

        // flash 동영상 참고
        // 이전 강의와 비교하며 여러번 보기
        System.out.println("참조형 매개변수 : 변수의 값을 읽고 변경을 할 수 있다.");
        System.out.println("참조형 반환타입 : 복사한 객체의 주소를 반환한다.");
        
        // 참조형 매개변수 예제
        Data2 d = new Data2(); // 객체 생성
        d.x = 10; // 참조변수 d가 가리키는 x객체에 10을 넣겠다.
        System.out.println("main : " + d.x); // x는 10이 출력된다.

        Data2.change(d); // change 메서드 호출
        System.out.println("After change(d.x)");
        System.out.println("main : " + d.x);

        // 참조형 반환타입 예제
        Data3 dd = new Data3();
        d.x = 10;

        Data3 d2 = Data3.copy(dd); // 같은 클래스에 위치하기 때문에 참조변수 없이 호출이 가능하다.
        System.out.println("d.x = " + d.x);
        System.out.println("d2.x = " + d2.x);

    } // main의 끝
}

// 참조형 매개변수
class Data2 {
    int x;

    static void change (Data2 d) { // static이기때문에 자동으로 객체생성을 해준다.
        d.x = 1000; // change메서드 안에 있는 x변수는 지역변수다. d.x와 다른 x이다. 참조형 매개변수이기때문에  d.x를 변경하는 것이 가능하다.
        System.out.println("change x : " + d.x); // d.x값은 1000이 출력된다.
    }
} // class의 끝

// 참조형 반환타입
class Data3 {
    int x;

    static Data3 copy(Data3 dd) { // static이기때문에 자동으로 객체생성을 해준다.
        Data3 tmp = new Data3(); // 새로운 객체 tmp를 생성한다.
        tmp.x = dd.x; // d.x의 값을 tmp.x에 복사한다.
        return tmp; // 복사한 객체의 주소를 반환한다.
    }
} // class의 끝