자바에서 객체들은 메모리에 어떻게 표시될까?

자바에서 객체들은 메모리에 어떻게 표시될까?

 

객체지향은 인간이 눈으로 보고, 느끼고, 생활하는 현실 세계처럼 프로그래밍을 할 수는 없을까? 라는 고민 속에서 탄생했다.

즉, 0과 1로 대변되는 기계에 맞춰서 사고하던 방식을 버리고 현실세계를 실제로 인지하는 방식으로 프로그램을 만들자는 것이다.

(객체지향이 현실 세계를 반영한다.)

 

객체지향의 큰그림

-세상에 존재하는 모든 것은 사물, 즉 객체이다.

-각각의 사물은 고유하다.

-사물은 속성을 갖는다.

-사물은 행위를 한다.

 

그리고 사물을 하나하나 이해하기 보다는 사물을 분류(class)해서 이해하는 것이 인간의 인지법이다.

-직립보행을 하며 말을 하는 존재를 사람이라고 분류한다.

-밤하늘의 반짝이는 사물을 별이라고 분류한다.

 

손흥민, 김종민 이라고 하는 존재는 사람이라는 분류에 속한다.

그리고 사람이라는 분류 안의 객체들은 나이, 몸무게, 키 등의 속성과 먹다, 자다, 울다 등의 행위를 가지고 있다.

 

객체지향의 4대 특성

캡슐화: 정보은닉

상속: 재사용

추상화 : 모델링

다형성:사용편의

 

 

클래서 vs. 객체 = 붕어빵틀 vs 붕어빵 ???

 

클래스 객체명 = new 클래스();

 

붕어빵틀 붕어빵 = new 붕어빵틀(); // ??

 

붕아빵틀을 생산하는 금형기계가 있다고 가정해보자.

그럼 붕어빵틀이 붕어빵을 찍어내서 클래스라고 한다면 같은 논리로 금형 기계는 붕어빵틀을 찍어내는 클래스가 된다.

 

금형기계 붕어빵틀 = new 금형기계();

 

이 코드를 말로 해보면?

 

새로운 금형기계를 하나 만들었는데 붕어빵 틀이 되었다?

 

말이 안된다. 즉, 금형기계와 붕어빵틀이 클래스와 객체 관계가 아니듯 붕어빵과 붕어빵틀도 클래스와 객체 관계가 아니다.

 

그럼 붕어빵에게 붕어빵틀은 무엇인가? 붕어빵틀은 붕어빵을 만드는 팩터리였던것이다.

 

 

다음 문제들에 답해보자

1.사람은 클래스인가 객체인가?

2.손흥민은 클래스인가 객체인가?

 

1.사람의 나이는 몇살인가?

2.손흥민의 나이는 몇살인가?

 

 

-클래스와 객체를 구분할때는 이름이나 나이를 물어보면 된다.

 

1번은 답을 할수 없지만 2번은 답을 할 수가 있다. 

즉, 클래스는 분류에 대한 개념이지 실체가 아니다.

 

 

 

 

1.추상화 - 모델링

 

사전적의미 :  여러가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용

 

“객체 지향의 추상화는 곧 모델링이다”

 

추상화란 구체적인 것을 분해해서 관찰자가 관심 있는 특성만 가지고 재조합하는 것이라고 정리할 수 있다.

 

여기서 객체와 클래스의 정의를 짚고 넘어가자.

 

객체는 세상에 존재하는 유일무이한 사물이다.

 

클래스는 분류,집합 같은 속성과 기능을 가진 객체를 총칭하는 개념이다.

 

공식하나

클래스:객체 = 팽귄:뽀로로 = 사람:손흥민 = 쥐:제리

 

세상에 존재하는 유일무이한 객체들 특성(속성+기능)에 따라 분류해 보니 객체를 통칭할 수 있는 집합적 개념, 즉 클래스(분류)가 나오게 된다.

 

새로운 사람이 태어 났는데 이번에는 이름을 메시라고 해보자

 

사람 메시 = new 사람();

 

사람이라는 클래스(분류)를 이용해 유일무이하고 새로운 하나의 사람(객체)을 만들어 메시(객체 참조 변수)라는 이름을 지어준 것이다.

 

클래스는 영어로 class

객체는 영어로 object

 

그런데 클래스를 이용해 object를 만들었다는 것을 강조할 때는 object라는 표현보다는 클래스의 인스턴스(instance)라는 표현을 쓴다.

 

객체(object) = 클래스의 인스턴스

 

컴퓨터 프로그램을 만드는 과정에서 개발자는 바로 해당 어플리케이션의 창조자가 된다.

그래서 우리도 객체 지향 프로그래밍을 할 때 클래스를 먼저 설계하게 된다.

 

그런데 이게 객체지향과 무슨관련이 있나?

 

사람이라는 클래스를 만든다고 가정해보자.

 

사람 클래스를 만들기 위해 주변에서 보이는 실체들, 즉 사람 객체들을 관찰해서 사람 객체들이 가진 공통된 특성(속성+행위)를 찾게 된다.

 

시력, 몸무게, 키,…

 

먹다..자다…일하다…

 

사람의 특성을 모두 나열해보고 싶지만 모두다 나열할 수가 없다. 엄청 많기 때문이다.

 

그래서 경계가 필요하다. 때로는 애플리케이션의 경계를 컨텍스트라고 부르기도 한다.

 

이 경계를 알기위해서는 질문을 하나 던져보면된다.

 

“내가 창조하려는 세상은 어떤 세상인가?”

 

“내가 만들고자 하는 앱은 어디에 사용될 것인가?”

 

만약 병원 앱을 만들고 있다면 사람은 환자를 의미하는 더 구체적인 이름으로 바꿀 수 있다.

클래스 설계도 달라지게 된다.

 

추상화: 구체적인것을 분해해서 관심 영역에 대한 특성만 가지고 재조합하는것.

 

 

 

자바에서 객체들은 메모리에 어떻게 표시될까?

 

모델은 실제 사물을 정확히 복제하는 것이 아니라 목적에 맞게 관심 있는 특성만을 추출해서 표현하는 것이다.

바로 모델은 추상화를 통해 실제 사물을 단순하게 묘사하는 것이다.

 

중요

OOP의 추상화는 모델링이다.

클래스 : 객체 = 팽귄 : 뽀로로

클래스 설계에서 추상화가 사용된다.

클래스 설계를 위해서는 애플리케이션의 경계부터 정해야 한다.

객체 지향에서 추상화의 결과는 클래스다.

 

클래스와 객체 관계를 자바에서는 어떻게 표현할까?

 

클래스 객체_참조_변수 = new 클래스();

 

 

 

추상화와 메모리

 

MouseDriver.main() 메서드가 시작점이니 main 메서드를 실행하기 전의 메모리는 아래와 같다.

Java.lang 패키지와 모든 클래스들이 메모리 스태틱 영역에 배치된다.

 

그런데 Mouse 에서 name, age 에는 변수 저장공간이 안보인다. 이름만 존재할 뿐이다.

이 속성들은 Mouse 클래스에 속한 속성이 아닌 Mouse 객체에 속한 속성이기 때문이다.

객체가 생성되어야만 속성의 값을 저장하기 위한 메모리 공간이 스태틱 영역이 아닌 힙 영역에 할당된다.

 

그리고 MouseDriver 클래스의 main() 메서드에는 밑줄이 있고, Mouse 클래스의 sing() 메서드에는 밑줄이 없다.

main() 클래스는 클래스의 멤버 메서드이고, sing()은 객체의 멤버 메서드이기 때문이다.

클래스 멤버와 객체 멤버를 구분하는 자바 키워드는 static이다.

 

이제 객체가 메모리상에 어떻게 저장이되는지 알아보자

 

5번째줄을 보자

 

// Mouse 객체에 대한 참조 변수 mickey를 만든다. 

Mouse mickey 

 

// Mouse 클래스의 인스턴스를 하나 만들어서 힙에 배치한다.

new Mouse()

 

대입

// Mouse 객체에 대한 주소 (포인터)를 참조 변수 mickey에 할당한다.

 

 

객체 참조 변수 mickey가 Mouse 객체에 대한 참조 변수라는 것을 알 수 있다.

 

5번째줄을 의역하면 아래와 같다.

 

 

 

 

13번째 줄에서 객체 참조 변수 mickey에 null을 할당하고 있다.

 

13번째 줄이 실행된 후에는 객체 참조 변수 mickey가 더 이상 힙 영역에 존재하는 Mouse 객체를 참조하지 않는다.

 

그러면 가비지 컬렉터가 아무도 참조해 주지 않는 Mouse 객체를 쓰레기로 인지하고 수거해간다.

 

 

 

 

참고 : 스프링 입문을 위한 자바 객체 지향의 원리와 이해