<1주차 복습>

변수

1단계

  • 변수란? 변하는 값을 담은 것
  • 타입 변수명; : 선언만 한 것
  • 타입 변수명 = 값; : 선언+초기화
  • 변수의 종류: 원시형 타입 / 참조형 타입(클래스는 참조형 타입이다 ex. Pride, Sonata..)
  • 클래스 = 변수 + 메소드()

2단계

  • 변수는 메소드 선언 또는 메소드 호출시에도 사용 가능
  • 변수가 올 수 있는 위치
    1) 리턴타입 자리(원시형타입, 참조형타입 둘 다 가능)
    2) 파라미터 자리

*그럼 1번과 2번은 어떤 차이가 있을까?

1) 리턴타입은 선언하는 자리가 아니기 때문에 타입만 오고 변수명은 오지 않는다 (리턴타입의 클래스를 자유롭게 사용할 수 있도록 연습하자)
2) 파라미터 자리는 지역변수를 선언하는 자리니까 변수명이 와야 한다
ex. methodA(int) : X → methodA(int i)
: 이렇게 변수명까지 와야하는 것

파라미터 자리에 선언한 변수 i는 정수형을 담을 수 있는 타입이면서 변수의 이름은 i이고, 그 메소드 안에서 초기화를 반드시! 꼭! 해줘야 한다. (이게 전역변수와의 차이. 전역변수는 초기화를 생략할 수 있으니까. 그러나 지변은 초기화 생략 불가!-> 실행할 때 런타임에러 발생하니까~)

2) 파라미터 자리에는 변수선언이 없어도 되고, 하나여도 되고, 여러 개도 괜찮아!
1-2: 파라미터 자리는 사용자가 화면에 입력한 아이디나 비번이나를 담아주는 역할을 하는 것이다

3단계
원시형 타입뿐 아니라 참조형 타입을 파라미터로 사용할 수 있도록 대비하자

<예시1-1>
package com.week1;

class Dog {
	int leg = 4; // 클래스 선언 바로 뒤에 붙여서 선언하기
	public void running() {
		int leg = 6;
        System.out.println(leg);
	}
}

public class wVariable1 {
	
	public static void main(String[] args ) {
		Dog myDog = new Dog();
		System.out.println(myDog.leg);
        // Dog.class가 생성되었다는 의미
        // 4 출력(전변이 호출되었다는 것)
		System.out.println(6);
        // 6이 출력은 됐지만, 변수가 아님
	}
}
출력: 4
	 6
  • int leg = 4;를 출력하기 위해 인스턴스화를 했다

  • 인스턴스화: 메모리에 로딩 중. 메모리에 존재하는 것(언제든지 부르면 나올 수 있게 끼워져있다)

  • 왜 System.out.println(leg);는 출력되지 않았을까?

<예시 1-2> : 처리순서
package com.week1;

class Dog {
	int leg = 4; // 순서3 
	public void running() {
		int leg = 6;
		System.out.println(leg);
	}
}

public class wVariable1 {

	public static void main(String[] args ) { // 순서1
		Dog myDog = new Dog(); // 순서2
		System.out.println(myDog.leg);  //순서 4
		System.out.println(6); // 순서5
	}
}

running 메소드는 어느 클래스에 선언되어 있죠?
그 클래스가 인스턴스화 되어있니? -> 이걸 확인해야 하고
만약 그렇다면 나는 할 수 있다!가 돼야 한다. 뭘? 러닝 메소드 호출해서 leg 호출

<예시1-3>
package com.week1;

class Dog {
	int leg = 4;
	public void running() {
		int leg = 6;
		System.out.println(leg);
	}
}

public class wVariable1 {

	public static void main(String[] args ) { 
		Dog myDog = new Dog(); 
		System.out.println(myDog.leg); 
		System.out.println(6); 
		myDog.running();
        // 이걸 추가하면 위에 6이 출력된다!
	}
}
  • 이클립스에서는 전변 - 하늘색 / 지변 - 노란색으로 작성 됨

파라미터 인스턴스화

<예제1>
package com.week1;

class Account {
	public void hap1() {
	}
	public void hap2(int first, int second) { 
		System.out.println(first+second);
		first = 0; 
		second = 1;
		System.out.println(first+second);
	}
} 

public class AccountSimulation {

	public static void main(String[] args) {
		Account as = new Account();
		as.hap2(1, 3);
	}
}
<예제1 - 주석 설명>
package com.week1;
// Account라는 클래스는 사용자로부터 임의의 두 수를 입력받아서 
// 두 수의 합을 구하는 메소드를 구현하기 위해 설계되었다
class Account {
	// 파라미터를 사용하지 않고 계산한 결과를 구하려면 전변 사용해야 한다
	public void hap1() {
	}
	// 아래 메소드는 두 수를 파라미터로 받아서 계산하므로, 지변으로 가능하다
	// 파라미터 자리에서는 초기화를 할 수 없다
	// (int first = 0, int second=100) 이런 식으로 안 된다고!
	// 지변은 반드시 초기화를 해야만 한다
	// 그럼 언제 어느 위치에서 가능할까요?
	// 파라미터 자리의 변수 값은 호출될 때 결정되지만 
	// 호출되는 메소드 안에서 다른 값으로 변경될 수도 있다
	
	public void hap2(int first, int second) { //first=1, second=3 넘어와서 바로 밑에서는 4 출력
		System.out.println(first+second);
		first = 0; // 2. 그래서 초기화 해줌. 선언은 이미 같은 메소드에서 해줬기 때문에 중복 선언 불가능
		second = 1; // 여기 재정의하면서 0, 1 넘어와서 1 출력
		System.out.println(first+second); // 1. 이거 출력하면 에러남. 왜? 초기화를 안 했기 때문
	}
} // end of Account

public class AccountSimulation {

	public static void main(String[] args) {
		Account as = new Account();
		as.hap2(1, 3);
	}
}
<예제2>
package com.week1;

class Account {
	int first; // 이것은 전변이라서 초기화를 하지 않아도 0을 가지고 있다
	int second;
	// int first, second; // 이렇게 작성해도 됨
	
	public void hap1() { // 메소드 호출은 메인메소드 안에서 해야 합니다. 왜? 내가 하는 게 아니고 JVM 시키는 거니까
		System.out.println(first+second); // 0+0 => 0
		// 여기에 출력하는 문장이 있어도 hap1()메소드를 호출하지 않으면 실행기회를 갖지 못한다
	}
	
	public void hap2(int first, int second) { 
		System.out.println(first+second);
		first = 0; 
		second = 1; 
		System.out.println(first+second); 
	}
} 

public class AccountSimulation {

	public static void main(String[] args) {
		
		Account as = new Account();
		as.hap2(1, 3);
		// as.hap2(); // 이거 땡. 파라미터의 개수와 타입((0, false)(0, "안녕") 이런 식으로)이 맞지 않아서
		as.hap1(); // 이건 파라미터에 값이 (땡땡, 땡땡) 들어있는 것이 아니기 때문에 그냥 공백으로 두면 들어있는 값인 0을 위에서 출력하는 것
	}
}

메소드 호출

<예시>
package com.week1;

public class MethodCall {
	void methodA() {
		System.out.println("methodA");
	}
	void methodB() {
		System.out.println("methodB");
		methodA();
		//methodB 안에서 methodA()를 호출하는 것도 합법이다
	}
	public static void main(String[] args) {
		MethodCall mc = new MethodCall();
		mc.methodB();
	} // methodB를 호출하면 methodA까지 같이 호출 됨
}
출력: methodB
     methodA
  • 클래스 안에 메소드가 선언되어 있다고 하더라도 호출하지 않으면 실행되지 않는다
  • 다른 메소드 안에서도 다른 클래스에 있는 메소드를 호출할 수 있지만, 우리가 작성한 코드를 실제로 실행하는 것은 JVM이므로 메인메소드 안에서 호출하는 것이 그 시작이다

리턴타입

<예시1>
package com.week1;

public class Print1 {
	static int m() {return 5;}
	static void n() {}
	public static void main(String[] args) {
		System.out.println(1);
		System.out.println("안녕");
		System.out.println(1.5);
		System.out.println(true);
		// 메소드의 파라미터 자리에서 또 다른 메소드를 호출할 수도 있다
		// 단, 리턴타입이 void인 건 아니다(예외)
		System.out.println(Print1.m()); // 출력 5
		System.out.println("================");
		~~System.out.println(Print1.n());~~
        // 이건 안 된다. 왜? 리턴타입이 void라서
	}
}
  • 메소드 선언 문장 형식
    (접근제한자-생략 가능)+리턴타입+메소드이름(파라미터자리1,2...)
  • 메소드 선언시 리턴타입이 오는 자리에 void가 있다면 return 예약어 쓸 수 없다
  • 리턴되는 값이 없다면 다른 메소드에서 그 메소드가 가진 데이터를 재사용할 수 없다
<예시2>
package com.week1;

public class WReturn1 {
	void methodA() {
		~~return 1;~~ // void가 있는데 리턴을 쓰면 에러
	}
	// 만일 여러개의 값을 반환하고 싶다면 참조형 타입을 사용하면 된다(3단계 수준)
	int methodB() { // 리턴 다음에 오는 코드는 반드시 타입을 맞춰야 함
		return 1; // 하나만 반환할 수 있다
        // 만일 여러개의 값을 반환하고 싶다면 참조형 타입을 사용하면 된다(3단계 수준)
		~~return 1.5;~~
        // 이건 더블이기 때문에 안 된다. 타입을 맞춰야 한다
		return (int)1.5; 
        // .5는 못 들어오고 1로 리턴
	}
	public static void main(String[] args) {
		// 여기(메인메소드 안에서)에서 methodB의 반환값을 출력할 수 있다 없다
		// 여기에서 methodB의 반환값을 출력할 수 있을까?
		WReturn1 w = new WReturn1();
		~~w.methodB();~~ 
        // 이건 아무것도 출력이 안 됨
		// 리턴타입이 void가 아닌 것은 대입연산자를 써서 반환되는 값을 담을 수 있다
		int i = w.methodB(); 
        // 위에 리턴 1이 있으니 합법
		~~i = w.methodA();~~ 
        // 여긴 돌려받을 게 없으니 불가능
	}
}

		System.out.println(i);// 출력을 하려면 이렇게 변수를 출력하거나
		// 변수 i에 담지 않고 System.out.println(w.methodB());로 출력하거나
        
<예시3-1>
package com.week1;

public class WReturn2 {
	int i; // 전역변수 i
	void methodA() {
		int i = 2;
	}
	int methodB() {
		int i = 1; // 지역변수 i이다
		return i; // 1
	}
	public static void main(String[] args) {
		WReturn2 w = new WReturn2();
		// w.methodB(); // 왜 이게 없어도 출력이 되는거지?
		System.out.println(w.methodB());
	}
}

methodA()의 i 값(지변)은 왜 출력하려면 어떻게 할까?

<예시3-2>
package com.week1;

public class WReturn2 {
	int i; 
	void methodA() {
		int i = 2;
		System.out.println("i-> " +i); //
	}
	int methodB() {
		int i = 1; 
		return i;
	}
	public static void main(String[] args) {
		WReturn2 w = new WReturn2();
		System.out.println(w.methodB());
		w.methodA();
		System.out.println("W.i-> " + w.i); 
        // 이건 합법이지만, 전역변수 i가 호출되는 것
	}
출력: 1
i-> 2
W.i-> 0
<예시4>
package com.week1;
// 메소드의 파라미터로 참조형을 사용하는 방법에 대해서 알려주세요
class Sonata { 
	int speed = 0; // 현재 소나타는 주차되어 있다
	String carColor = "빨강"; 
}
public class Wreturn3 {
	// 메소드에 리턴타입으로 참조형 변수를 사용할 수 있다
	// 메소드 호출을 통해서도 클래스를 메모리에 로딩할 수 있다
	Sonata getCar() {
		Sonata himCar = new Sonata(); // 소나타 객체를 생성하였다
		return himCar; // return으로 그 변수를 반환할 수 있다
	}
	public static void main(String[] args) {
		Wreturn3 w = new Wreturn3(); 
		// 인스턴스를 한 이유는 getCar() (메소드)를 호출하기 위해서
		Sonata myCar = new Sonata();
		System.out.println(myCar.carColor); // 빨강
		Sonata himCar = w.getCar();
		// 여기서 getCar메소드를 호출했고, 
		// 리턴타입으로 Sonata 객체를 참조하는 변수가 선언되었다
		System.out.println(myCar);
		System.out.println(himCar);
		himCar.carColor = "검정색"; // 차 색상을 빨강 아닌 검정으로
		// 검정색 자동차는 현재 30km 달리고 있고
		// 빨강 자동차는 현재 0
		System.out.println(himCar.carColor); // 검정색
		himCar.speed = 30;
		System.out.println(himCar.speed); // 30
	}

}


3개 row를 다 담을 수 있는 코드를 적어보자

<step1>
package com.week1;

public class DeptSimulation {

	public static void main(String[] args) {
		Dept dept = new Dept();
		System.out.println(dept);
		dept = new Dept();
		System.out.println(dept);
		dept = new Dept();
		System.out.println(dept);
	}
}
출력: com.week1.Dept@6f2b958e
     com.week1.Dept@5e91993f
     com.week1.Dept@1c4af82c
<step2>
package com.week1;

public class DeptSimulation {
	// 타입은 Dept타입인데 주소번지는 서로 달라요
	public static void main(String[] args) {
		Dept dept = new Dept();
		dept.deptno = 10;
		System.out.println(dept); // @6f2b958e
		System.out.println(dept.deptno); // 10
		dept = new Dept();
		dept.deptno = 20;
		System.out.println(dept.deptno); // 20
		System.out.println(dept);// @5e91993f
		dept = new Dept();
		System.out.println(dept); //@1c4af82c
		System.out.println(dept.deptno); 
	}
}
<예시1-1>
package com.week1;

public class Emp {
	// 사원번호를 담을 변수 선언
	int empno = 0;
	// 사원이름을 담을 변수 선언
	String ename 	= null;
	String job 		= null;
}
// 7566 나신입 마케팅
<예시1-2>
package com.week1;
//int의 디폴트값이 0으로 약속된 것처럼 클래스의 디폴트 값은 null로 되어있다.
public class EmpSimulation {
	// main메소드에서 출력하던 문장을 empPrint메소드로 꺼내서 처리하시오
	//public void empPrint(?) {
	//	System.out.println(emp.empno + ","+emp.ename+","+emp.job);
		
	//}
	
	public static void main(String[] args) {
		Emp emp = new Emp();
		// 0, null, null
		System.out.println(emp.empno + ","+emp.ename+","+emp.job);
		emp.empno = 7566; // 초기화, 재정의되었다
		emp.ename = "나신입";
		emp.job = "마케팅";
		System.out.println(emp);
		System.out.println(emp.empno + ","+emp.ename+","+emp.job);
		// 새로운 신입사원이 한 명 더 입사하였다.
		// 그 사원의 사원카드를 작성해 보시오
		// 7499 나초보 매니저
		emp.empno = 7499; // 초기화, 재정의되었다
		emp.ename = "나초보";
		emp.job = "매니저";
		System.out.println(emp.empno + ","+emp.ename+","+emp.job);
		
	}

}
<예시1-3>
package com.week1;
//int의 디폴트값이 0으로 약속된 것처럼 클래스의 디폴트 값은 null로 되어있다.
public class EmpSimulation {
	// main메소드에서 출력하던 문장을 empPrint메소드로 꺼내서 처리하시오
	public void empPrint(Emp emp) { // 파라미터 자리는 지변 자리다. 호출될 때 결정된다.
		System.out.println(emp.empno + ","+emp.ename+","+emp.job);
	}
	
	public static void main(String[] args) {
		EmpSimulation es = new EmpSimulation();
		Emp emp = new Emp();
		// 0, null, null
		System.out.println(emp.empno + ","+emp.ename+","+emp.job);
		emp.empno = 7566; // 초기화, 재정의되었다
		emp.ename = "나신입";
		emp.job = "마케팅";
		es.empPrint(emp);
		// System.out.println(emp);
		// System.out.println(emp.empno + ","+emp.ename+","+emp.job);
		// 새로운 신입사원이 한 명 더 입사하였다.
		// 그 사원의 사원카드를 작성해 보시오
		// 7499 나초보 매니저
		Emp emp = new Emp();
		emp.empno = 7499; // 초기화, 재정의되었다
		emp.ename = "나초보";
		emp.job = "매니저";
		// System.out.println(emp);
		// System.out.println(emp.empno + ","+emp.ename+","+emp.job);
		es.empPrint(emp);
		
	}

}
<예제1-4>
package com.week1;

public class DeptSimulation {
	// 타입은 Dept타입인데 주소번지는 서로 달라요
	public static void main(String[] args) {
		Dept dept = new Dept(); // 이것만 선언
		dept.deptno = 10;
		dept.dname = "개발부";
		dept.loc = "서울";
		System.out.println(dept); // @6f2b958e
		System.out.println(dept.deptno+","+dept.dname+","+dept.loc); 
		dept = new Dept(); // 이것은 선언 아님. 재정의
		dept.deptno = 20;
		dept.dname = "운영부";
		dept.loc = "대전";
		System.out.println(dept.deptno+","+dept.dname+","+dept.loc); 
		System.out.println(dept);// @5e91993f
		dept = new Dept(); 
		dept.deptno = 30;
		dept.dname = "기획";
		dept.loc = "제주";// 이것은 선언 아님. 재정의
		System.out.println(dept.deptno+","+dept.dname+","+dept.loc); 
		System.out.println(dept); //@1c4af82c
	}
}
출력: com.week1.Dept@6f2b958e
10,개발부,서울
20,운영부,대전
com.week1.Dept@5e91993f
30,기획,제주
com.week1.Dept@1c4af82c

/*
 * 같은 이름의 변수이더라도 new를 사용해서 인스턴스화를 하면 새로운 객체가 만들어진다
 * 이 때 변수가 3개 정의되어 있으므로 Dept 클래스 선언시 주었던 초기값을 디폴트 값으로 
 * 기억하고 있다
 */
<Emp 클래스>
package com.week1;

public class Emp {
	// 사원번호를 담을 변수 선언
	int empno = 0;
	// 사원이름을 담을 변수 선언
	String ename 	= null;
	String job 		= null;
}
// 7566 나신입 마케팅
package com.week1;

public class EmpSimulation2 {
	void setEmp(Emp emp) {
		emp.empno = 7566;
		emp.ename = "Smith";
		emp.job = "영업";
		System.out.println("===========[before]============");
		System.out.println(emp.empno+","+emp.ename+","+emp.job); // 7566, Smith, 영업출력됨
	}
	public static void main(String[] args) {
		EmpSimulation2 es2 = new EmpSimulation2(); // 4번 메소드를 호출하기 위해서 인스턴스화 하였음
		Emp emp = new Emp(); // 사원집합을 관리하는 클래스를 인스턴스화 하였음
		es2.setEmp(emp); // 메소드 호출할 때 파라미터로 13번에서 선언한 인스턴스변수를 넘겨줌
		System.out.println("===========[after]============");
		System.out.println(emp.empno+","+emp.ename+","+emp.job);
	}

}

package com.week1;

public class EmpSimulation2 {
	// main메소드에서 인스턴스화 한 Emp의 주소번지(지역번지)를 setEmp 즉 다른 메소드에서 사용하려면
	// 메소드의 파라미터 자리를 이용하세요
	// 만일 이해되었다면 after에서는 0, null, null이 출력되도록 코드 변경
	void setEmp(Emp emp) { // Emp emp =null에서 Emp emp = new Emp();로 변경.
		// 파라미터로 선언된 지변 emp는 호출됐을 때 null일까 아닐까? -> 
		emp.empno = 7566; // 초기화 // 이 문장이 실행되면서 0이 7566으로 변경됨(덮어쓰기)
		emp.ename = "Smith"; // 초기화 // null -> Smith로 변경
		emp.job = "영업"; // 초기화 // null -> 영업으로 변경
		System.out.println("===========[before]============");
		System.out.println(emp.empno+","+emp.ename+","+emp.job); // 7566, Smith, 영업출력됨
	} // end of setEmp
	public static void main(String[] args) {
		EmpSimulation2 es2 = new EmpSimulation2(); // 4번 메소드(void setEmp(Emp emp))를 호출하기 위해서 인스턴스화 하였음
		Emp emp = new Emp(); // 사원집합을 관리하는 클래스를 인스턴스화 하였음. 객체 생성
		es2.setEmp(emp); // 메소드 호출할 때 파라미터로 13번에서 선언한 인스턴스변수를 넘겨줌
		// (emp) 이 emp 안에는 어떤 값이 들어있을까? 0, null, null
		System.out.println("===========[after]============");
		System.out.println(emp.empno+","+emp.ename+","+emp.job); // 여기서는 어떤 값들이 출력되는 걸까요?
	}

}
// before가 먼저 출력. 왜냐하면 es2.setEmp(emp);로 setEmp라는 메소드를 먼저 호출했으니 after보다 먼저 출력
출력: ===========[before]============
7566,Smith,영업
===========[after]============
7566,Smith,영업

// 만일 이해되었다면 after에서는 0, null, null이 출력되도록 코드 변경

package com.week1;

public class EmpSimulation2 {
	// main메소드에서 인스턴스화 한 Emp의 주소번지(지역번지)를 setEmp 즉 다른 메소드에서 사용하려면
	// 메소드의 파라미터 자리를 이용하세요
	void setEmp(Emp emp) { // Emp emp =null에서 Emp emp = new Emp();로 변경.
		// 파라미터로 선언된 지변 emp는 호출됐을 때 null일까 아닐까? -> 
		emp = new Emp(); 
		emp.empno = 7566; // 초기화 // 이 문장이 실행되면서 0이 7566으로 변경됨(덮어쓰기)
		emp.ename = "Smith"; // 초기화 // null -> Smith로 변경
		emp.job = "영업"; // 초기화 // null -> 영업으로 변경
		System.out.println("===========[before]============");
		System.out.println(emp.empno+","+emp.ename+","+emp.job); // 7566, Smith, 영업출력됨
	} // end of setEmp
	public static void main(String[] args) {
		EmpSimulation2 es2 = new EmpSimulation2(); // 4번 메소드(void setEmp(Emp emp))를 호출하기 위해서 인스턴스화 하였음
		Emp emp = new Emp(); // 사원집합을 관리하는 클래스를 인스턴스화 하였음. 객체 생성
		es2.setEmp(emp); // 메소드 호출할 때 파라미터로 13번에서 선언한 인스턴스변수를 넘겨줌
		// (emp) 이 emp 안에는 어떤 값이 들어있을까? 0, null, null
		System.out.println("===========[after]============");
		System.out.println(emp.empno+","+emp.ename+","+emp.job); // 여기서는 어떤 값들이 출력되는 걸까요?
	}

}
// before가 먼저 출력. 왜냐하면 es2.setEmp(emp);로 setEmp라는 메소드를 먼저 호출했으니 after보다 먼저 출력
출력: ===========[before]============
7566,Smith,영업
===========[after]============
0,null,null

Q. 문제: main 메소드에서 생성한 객체를 다른 메소드에서 사용하고 싶다면 어떡하지?

<정답>
package com.week1;
class C {
	int i = 1;
} // end of C
public class Csimulation {
	void methodA(C c) {
		System.out.println("methodA===> "+c.i);
	}

	public static void main(String[] args) {
		// void methodA(C c)을 호출하기 위해 인스턴스화 했음
		Csimulation cs = new Csimulation();
		// methodA()를 호출할 때 파라미터로 C클래스의 인스턴스를 넘기기 위해 인스턴스화함
		C c = new C();
		cs.methodA(c); // 메소드 호출시 파라미터 자리에 C c = new C(); 에서 생성한 변수를 넘김
		System.out.println("main===> "+c.i); // C클래스에 선언한 전변i를 호출함
	} // end of main
} // end of CSimulation

0개의 댓글