반응형

*일반 변수에 값 할당되는 과정 설명

class Main {
	public static void main(String[] args) {
		
		int x;	
		x = 20; 
        
	}
}

int x;

- 오직 정수만 담을 수 있는 변수 x 생성.

- 초기에는 x에 쓰레기 값이 0이 들어간다. 왜냐하면 규칙상 x에 정수가 아닌 값이 들어있으면 안되기 때문이다.

- 앞에 int는 x에 정수만 들어갈 수 있다는 뜻이다.

 

x = 20;

- x에 기존에 저장되어 있던 쓰레기 값이 사라지고 20이 들어간다(저장된다.)

 

*래퍼런스 변수에 값 할당되는 과정 설명

class Main {
	public static void main(String[] args) {
		자동차.달리다();	
		자동차 a자동차;
		a자동차 = new 자동차();
		a자동차.달리다();
	}
}
class 자동차 {
	void 달리다() {
		System.out.println("자동차가 달립니다.");
	}
}

자동차.달리다( );

- 자동차 설계도에게 달리라고 한 꼴로 오류가 발생한다.

 

자동차 a자동차;

- 오직 자동차 리모콘만 저장 할 수 있는 변수 'a자동차'를 만든다.

- 'a자동차'에는 자동차 클래스로 만든 리모콘(쓰레기 리모콘)이 들어가게 된다.

- 설명 2) 자동차를 조종할 리모콘을 저장할 변수 'a자동차'를 만든다.

- 설명 2) 기본적으로 'a자동차' 변수에는 쓰레기 리모콘이 담긴다.

 

a자동차 = new 자동차( );

- 자동차 설계도(class 자동차)로 자동차 객체를 변수 외부에 만든다.

- 자동차 객체는 자신을 조종할 수 있는 리모콘(this)를 가지고 태어난다. 즉 자동차 객체를 만들 때 자동차 리모콘도 같이 만들어진다.

- 자동차 객체는 자신이 들고 있는 리모콘(this)를 복사해서 반환한다.

- a자동차 안에 들어있던 쓰레기 리모콘이 진짜 리모콘으로 대체된다.

- 설명 2) 자동차 객체를 생성하고 객체를 조종할 리모콘을 'a자동차'에 넣는다.

 

a자동차.달리다( );

- 'a자동차' 변수 안에 있는 리모콘의 '달리다' 버튼을 누른다.

- 해당 신호가 리모콘과 연결되어 있는 자동차 객체에 전달되어 '달리다' 기능이 실행된다.

- 설명 2) a자동차 변수안에 있는 리모콘의 '달리다' 버튼을 누른다.

 

class 자동차{ }

- 자동차 설계도를 의미하며, 절대 자동차가 아니다.

- 이 메서드(함수)는 실제 기능, 리모콘 버튼의 2가지 용도가 있다.

- 설명 2) class는 객체를 만들기 위한 설계도, 틀을 의미한다.

- 설명 2) 설계도로 할 수 있는 것 2가지(객체 만들기, 객체를 조종 할 수 있는 리모콘 만들기)

 

void 달리다( ){ };

- 달리다 함수/메서드

*모든 객체들은 서로를 평생 볼 수 없다, 모든 객체들은 서로를 원격조종한다.

 

*static 메서드

class Main {
	public static void main(String[] args) {
		자동차.달리다();
	}
}
class 자동차 {
	static void 달리다() {
		System.out.println("자동차가 달립니다.");
	}
}

static void 달리다() {}

- static을 사용하면 객체화 없이 설계도(class 자동차, 자동차 메서드(함수))에 있는 능력을 바로 쓸 수 있다.

 

*일반 변수

class Main {
	public static void main(String [] args) {
		int a;
	}
}

int a;

- 오직 main 함수 안에서만 활동하는 지역변수를 만들겠다는 것.

- main 함수에서는 더 이상 a라는 이름의 다른 변수를 만들 수 없다.

- main 함수가 시작되면 a변수는 만들어지고, main 함수가 끝나면 a변수는 사라진다.

- a는 단 한 순간도 정수 이외의 값을 가질 수 없다.

- 현재 a에는 0 (쓰레기 값)이 들어가 있다.

- a에는 오직 int 범위(-21억 ~ 21억)의 정수만 들어갈 수 있다.

- a에 정수가 아닌 값을 넣으려고 시도하면 자동으로 정수화 되어 들어간다. (만약 정수화가 위험할 수 있는 가능성이 조금이라도 있다면 오류가 발생한다.)

 

*class 함수(메서드)

class Main {
	public static void main(String [] args) {

	}
}
class 무기 {
	void 공격() {
	}
}
class 칼 extends 무기 {
	void 사과를_깍다() {
		
	}
}

class 메서드(함수)

- 무기 객체, 무기 리모콘을 만들 수 있다.

- 무기 리모콘만 들어가는 변수를 만들 수 있다.

- 무기 리모콘은 버튼의 개수가 1개이다.

- 무기 객체는 기능의 개수가 1개이다.

 

*래퍼런스 변수

class Main {
	public static void main(String [] args) {
		게임.작동하다();
	}
}
class 게임{
	static void 작동하다() {
		무기 a무기;
		a무기 = new 무기();
	}
}
class 무기 {
	void 공격() {		
	}
}

무기 a무기;

- 오직 무기 리모콘만 저장 할 수 있는 변수가 만들어진다.(a무기)

- 해당 변수는 단 한순간도 무기 리모콘이 아닌 값이 들어 갈 수 없다.

- 현재 a무기 변수에는 쓰레기 리모콘이 들어있다.

- 해당 쓰레기 리모콘의 버튼 개수는 1개이다.(void공격)

- 쓰레기 리모콘의 버튼을 누르면 오류가 난다.(객체와 연결되어 있지 않기 때문에)

- a무기 변수에는 무기리모콘이 당연히 저장될 수 있다.

- a무기에 무기리모콘이 아닌 다른 리모콘이 저장 되려 할 때 해당 리모콘은 자동으로 무기 리모콘으로 변해서 저장된다. (다른 리모콘이 만약 무기 리모콘으로 바뀌는게 안전하지 않을 수 있으면 오류가 발생한다.)

- a무기 라는 변수(공간)은 '작동하다' 함수가 시작할 때 만들어 지고, '작동하다'함수가 끝나면 사라진다.

- 여기서 당연하게도 a무기에 들어있던 리모콘은 변수가 사라질 때 같이 사라진다.

 

a무기 = new 무기();

- 무기 객체는 객체들만 사는 나라(힙)에 저장되어 있고 그것의 수명은 '작동하다' 함수가 끝나는 것과 전혀 상관없이 계속 살아간다.

- 단 객체는 외부에 자신을 가리키는 리모콘의 개수가 0이 되면 힙 내부에 돌아다니고 있는 가비지 컬렉터에 의해 언젠가 제거된다.

 

*상속

class Main {
	public static void main(String [] args) {
	
	}
}
class 무기 {
	void 공격() {		
	}
}
class 칼 extends 무기 {
	void 사과껍질제거() {		
	}
}

class 칼 extends 무기(){}

- 무기 리모콘의 버튼은 1개 이고, 칼 리모콘의 버튼은 2개 이다.

- 무기 클래스에 메서드 3개를 더 넣으면 무기 리모콘의 버튼은 4개가 되고 칼 리모콘의 버튼은 5개가 된다.

- 칼 리모콘의 버튼 개수는 절대 무기 리모콘의 버튼 개수 보다 적을 수 없다.

- 다시말해 칼 리모콘을 무기 리모콘으로 바꿀 때 해야 할 일은 오직 버튼을 제거하는 일 밖에 없다.

- 하나의 리모콘을 다른 하나의 리모콘으로 바꾼다는 것은 결국 특정 버튼을 제거하고, 특정 버튼들을 추가하는 일이다.

- 버튼을 제거하는 일은 좀 더 불편해지는 일이지만 문제가 되진 않는다.(안전하다)

- 버튼을 추가하는 일은 좀 더 편리해지는 일이지만 문제가 될 가능성이 다분히 높다.(안전하지 못하다)

- 자바에서는 안전한 일은 자동으로 해주고, 안전하지 않은 일은 개발자의 동의를 받는다.

 

*형 변환

class Main {
	public static void main(String[] args) {
		사람 a사람 = new 사람();
		원숭이 a원숭이 = new 원숭이();
		
		동물 a동물 = a원숭이;
		원숭이 a원숭이2 = null;

		a원숭이2 = a동물;

		a원숭이2 = (원숭이)a동물;

		사람 a사람2 = null;
		
		a사람2 = (사람)a동물;
	}
}
abstract class 동물 {
	void 숨쉬다() {
		System.out.println("동물이 숨을 쉽니다.");
	}
}
class 사람 extends 동물 {
	void 말하다() {
		System.out.println("사람이 말을 합니다.");
	}
}
class 원숭이 extends 동물 {
	void 원숭이묘기를하다() {
		System.out.println("원숭이묘기를하다.");
	}
}

1) 아래 코드가 되는 이유

동물 a동물 = a원숭이;

원숭이 a원숭이2 = null;

- 원숭이 클래스가 동물 클래스를 상속받는 상황이다.

- 자바는 이제 원숭이가 동물 이라는 것을 안다.

- 설명 1) 동물리코몬으로 원숭이 객체를 조종해도 괜찮기 때문에 가능하다.

- 설명 2) 원숭이리모콘이 동물리모콘으로 자동으로 바뀌어도(자동형변환) 문제가 없기 때문에 가능하다.

- 설명 3) `a동물` 변수는 오직 동물객체랑 연결될 수 있다. 그런데 지금 원숭이 객체를 연결시키려고 하고 있다. 원숭이 객체는 동물객체이기 때문에 가능하다.

 

2) 아래 코드가 안되는 이유

a원숭이2 = a동물;

- 동물 리모콘은 원숭이 객체를 가리키고 있다. 그렇지만 자바는 동물 리모콘이 연결된 것이 동물 객체라는 것은 알지만 그게 사람객체인지 동물객체인지는 알 수 없다.

- a원숭이2 변수는 오직 원숭이 객체랑만 연결될 수 있다.

- 동물리모콘이 원숭이 리모콘으로 변해야 하는 상황이다.

- 기존 리모콘에 '원숭이묘기를하다' 버튼을 추가로 넣어야 하는 상황이다.

- 설명 1) 실제로 동물리모콘은 원숭이를 가리킨다. 하지만 자바는 그 사실을 알지 못하고 동물리모콘에 원숭이 아닌 다른 객체(예를들면 사람객체)가 연결되어 있지는 않을까 두려워 한다. 그렇기 때문에 임의로 동물리모콘에 `원숭이묘기를하다` 버튼을 추가하지 못한다.

 

3) 아래 코드가 되는 이유

a원숭이2 = (원숭이)a동물;

사람 a사람2 = null;

- 동물리모콘은 원숭이 객체를 가리키고 있다.  그렇지만 자바는 동물리모콘에 연결된 것이 동물객체라는 것은 알지만 그게 사람객체인지 알 수 없다.

- a원숭이2는 오직 원숭이 객체랑만 연결될 수 있다.

- 동물리모콘이 원숭이 리모콘으로 변해야 하는 상황이다.

- 기존 리모콘에 '원숭이묘기를하다' 버튼을 추가로 넣어야 하는 상황이다.

- 설명 1) 실제로 동물리모콘은 원숭이를 가리킨다. 하지만 자바는 그 사실을 알지 못하고 동물리모콘에 원숭이 아닌 다른 객체(예를들면 사람객체)가 연결되어 있지는 않을까 두려워 한다. 그렇기 때문에 임의로 동물리모콘에 `원숭이묘기를하다` 버튼을 추가하지 못하는 상황이다. 그래서 자바가 `(원숭이)` 즉 수동형변환을 해주었다. 이 상황에서 자바는 여전히 불안하긴 하지만 그냥 개발자 믿고 컴파일 오류를 발생하지 않는다. 

반응형

+ Recent posts