자바 객체지향의 원리와 이해 (1)


OOP란?
Object Oriented Programming = 객체 지향 프로그래밍

컴퓨터 프로그램을 “객체(Object)”들의 모임으로 파악하고자 하는 프로그래밍의 패러다임 중에 하나이다.
각 “객체(Object)” 들은 서로 메시지를 주고 받을 수 있으며 데이터를 처리할 수 있다.

OOP 장점

  1. 프로그램을 유연하고 변경이 용이하게 만든다.

  2. 프로그램의 개발과 보수를 간편하게 만든다.

  3. 직관적인 코드 분석을 가능하게 한다.

자바와 절차적 / 구조적 프로그래밍

JVM의 존재와 역할을 아는 것이 자바 개발 환경을 이해하는 데 필수적이다. JVM은 이름 그대로 가상기계다.
현실 세계에서 컴퓨터를 구동하기 위해서는 물리적 컴퓨터인 하드웨어와 운영체제, 그리고 그 위에서 구동될 소프트웨어가 필요하다.
거기에 더해 소프트웨어를 개발할 수 있는 개발 도구가 필요하다. 자바의 가상 세계는 다음과 같이 현실 세계를 모방하고 있다.

현실 세계 -> 가상 세계(자바 월드)
소프트웨어 개발 도구 -> JDK : 자바 개발 도구
운영체제 -> JRE : 자바 실행 환경
하드웨어(물리적 컴퓨터) -> JVM : 자바 가상 기계

현실 세계에서 소프트웨어, 즉 프로그램은 개발자가 개발 도구를 이용해 개발하고 운영체제를 통해 물리적 컴퓨터인 하드웨어 상에서 구동된다.
자바가 만들어 주는 가상 세계도 이와 마찬가지다.
자바 개발 도구인 JDK를 이용해 개발된 프로그램은 JRE에 의해 가상의 컴퓨터인 JVM 상에서 구동된다.

스크린샷 2020-10-26 오후 3 40 42

JDK는 자바 소스 컴파일러인 java.exe를 포함하고 있고 JRE는 자바 프로그램 실행기인 java.exe를 포함하고 있다.
자바 개발자는 본인이 사용 중인 플랫폼에 설치된 JVM용으로 프로그램을 작성하고 배포하면
각 플랫폼에 맞는 JVM이 중재자로서 각 플랫폼에서 프로그램을 구동하는 데 아무 문제가 없게끔 만들어주는 것이다.

JDK: Java Development Kit / 자바 개발 도구
JRE: Java Runtime Environment / 자바 실행 환경
JVM: Java Virtual Machine / 자바 가상 기계

main() 메서드 : 메서드 스택 프레임

main() 메서드는 프로그램이 실행되는 시작점이다.
main() 메서드가 실행될 때 메모리, 특히 T 메모리에서 어떤 일이 일어날까?

JRE는 먼저 프로그램 안에 main() 메서드가 있는지 확인한다.
main() 메서드가 확인되면, JRE는 프로그램 실행을 위한 사전 준비에 착수한다.

JVM에 전원을 넣어 부팅하는 것이다.
JVM은 부팅되면 목적 파일을 받아 실행시킨다.

JVM이 맨 먼저 하는 일을 전처리 과정이라고 하는데,
모든 자바에 반드시 포함되는 패키지가 있다. java.lang

JVM은 가장 먼저 java.lang 패키지를 T 메모리의 스태틱 영역에 가져다 놓는다.

main() 메서드가 실행되기 전 JVM에서 수행하는 전처리 작업들은 다음과 같다.

main() 메서드가 끝나면 JRE는 JVM을 종료하고 JRE 자체도 운영체제 상의 메모리에서 사라진다.
T 메모리도 사라지게 된다.
T 메모리 소멸, JVM 기동 중지, JRE가 사용했던 시스템 자원 운영체제에 반납

T 메모리의 힙 영역은 다음에 같이 공부하기로 하자.

지역 변수와 메모리 : 스택 프레임이 갇혔어요 !

변수는 메모리에 있다.
지역 변수, 클래스 멤버 변수, 객체 멤버 변수로 다른 목적을 갖고 있는데
스태틱 영역, 스택 영역, 힙 영역 각각 있는 곳도 다르다.

클래스 멤버 변수는 스태틱 영영에 한번 자리 잡으로 JVM이 종료될 때까지 고정된(static)
상태로 그 자리를 지킨다.

객체 멤버 변수는 힙에서 일생을 보낸다.
객체와 함께 가비지 컬렉터라고 불리는 메모리 회수기에 의해 일생을 마치게 된다.

한 가지 기억할 결론은
외부 스택 프레임에서 내부 스택 프레임의 변수에 접근하는 것은 불가능하지만
그 역은 가능하다.

멀티 스레드 / 멀티 프로세스의 이해

멀티 스레드의 T 메모리 모델은 스택 영역을 스레드 개수만큼 분할해서 쓰는 것이다.
멀티 프로세스는 다수의 데이터 저장 영역, 즉 다수의 T 메모리를 갖는 구조이다.

멀티 프로세스는 각 프로세스마다 각자의 T 메모리가 있어
각자 고유의 공간이므로 서로 참조할 수 없다.
멀티 스레드는 하나의 T 메모리만 사용하는데 스택 영역만 분할해서 사용하는 구조이다.
그래서 하나의 스레드에서 다른 스레드의 스택 영역에는 접근할 수 없지만 스태틱 영역과 힙 영역은 공유해서 사용하는 구조다.

따라서 멀티 프로세스 대비 멀티 스레드는 메모리를 적게 사용할 수 있는 구조이다.

자바와 객체 지향

객체 지향의 4대 특성 - 캡! 상추다

추상화는 모델링이다.

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

중요한 부분만 적어보자.

추상화를 넓게 본다면 아래의 내용도 포함이다.

상속 : 재상용 + 확장

상속 관계에서 반드시 만족해야 할 문장이 있다.

예를들어, 조직도와 분류도로 나눠 생각해보자.

조직도

위 예시는 이상하다.

분류도

자연스러운 예시이다.

“하위 클래스는 상위 클래스다.” 라는 문장과 객체지향 설계 5원칙 중 LSP를 나타내는 말이다.

마지막으로 정리해보자.

다중 상속과 자바

왜 자바는 다중 상속을 지원하지 않을까?

인어공주를 예로 들어보자.
인어는 사람과 물고기를 상속한다고 생각해보자.

스크린샷 2020-06-09 오후 5 30 12

물고기와 사람은 수영을 할 수 있다.
그런데 인어에게 “수영해!” 라고 했을 때, 인어는 팔과 다리로 헤엄칠까 아니면 지느러미로 헤엄칠까..?
어떤 부모의 헤엄 방법을 사용해야 하는지 충돌이 일어났다.

이와 같은 문제를 다중 상속의 다이아몬드 문제라고 한다.
결국 자바는 인터페이스를 도입해 다중 상속의 득은 취하고 실은 과감히 버렸다.

상속과 인터페이스

그럼 인터페이스는 왜 다중 상속이 가능할까?
인터페이스는 ‘무엇을 할 수 있는’ 이라는 표현의 형태로 만들어져
기능에 대한 선언만 있기 때문에 다중 상속에서 전혀 문제될게 없다.

그렇가면 아래의 문제들에는 어떤게 정답일까?

정답은,
상위 클래스는 물려줄 특성이 많으면 많을수록 좋고
인터페이스는 구현을 강제할 메서드의 수가 적은게 좋다.

상위 클래스가 풍성할수록 좋은 이유는 LSP 에 따른 이유이고,
인터페이스 메서드가 적을수록 좋은 이유는 ISP에 따른 이유라고 할 수 있다.

객체 지향 설계 5원칙 보러가기

캡슐화 : 정보 은닉

자바에서 정보 은닉이라고 하면 접근 제어자들이 생각난다.

단순하게 마무리 해보자면,

참조 변수의 복사

기본 자료형 변수를 복사하는 경우 Call By Value (값에 의한 호출)에 의해 그 값이 복사되며
두 개의 변수는 서로에게 영향을 주지 않는다.

그렇다면 기본 자료형이 아닌 객체를 저장하고 있는 객체 참조 변수를 복사하는 경우는 어떨까?

기본 자료형 변수는 저장하고 있는 값을 그 값 자체로 해석하는 반면,
객체 참조 변수는 저장하고 있는 값을 주소로 해석한다는 차이가 있다.

마지막으로 정리해보면,