객체지향 프로그래밍
자바를 공부하다 보면 객체지향 프로그래밍이란 것과 자주 마주치게 됩니다.
'객체지향' 이라 하면 센스껏 객체를 이용해서 프로그래밍하는 기법이겠거니 싶긴 합니다. 근데 개발자를 하고 싶다는 사람이 어디가서 이런식으로 밖에 얘끼하지 못하면 안되겠죠?
그래서 먼저 객체란 무엇일까를 고민해봤습니다.
객체지향 개념도👇
흔히 객체를 얘기하면 세상 모든 것을 표현한 것이라고 자주 말합니다. 더 애매하죠? 근데 어떻게 보면 세상 모든 것은 쉽게 생각해보면 개념이 있고 그 개념의 구성 요소와, 그 구성 요소의 동작으로 이루어져 있을 것입니다. 예를 들어 '축구경기'를 객체로 표현해 보겠습니다.
'축구 경기 구성요소'
'축구 경기 구성요소의 동작'
- '선수가 경기를 한다'
- '공이 굴러간다'
- '관중이 응원을 한다'
- '규칙을 적용시켜서 퇴장을 시킨다'
이렇게 요소와 동작으로 나타내보았는데 좀더 전문적인 표현으로 하면 위의 사진과 같이 속성과 메소드라고 합니다. 이러한 데이터를 담고 있는 것을 통상 객체라고 하고 자바에서는 이것이 클래스로 구현이 됩니다.
객체지향 프로그래밍 전에는 절차적 프로그래밍이 지배적이었는데, 그것에 비해 객체지향만이 갖는 이점이 무엇이기에 요즘 OOP의 중요성이 이렇게 커진 걸까요?
객체로 프로그래밍 하는 것은 다음과 같은 이점이 있습니다.
객체지향 프로그래밍의 장점
- 중복되는 코드의 재사용을 통한 개발 효율성 증대
- 접근제한자를 통해 보안성을 증대
- 개념단위로 객체를 구현함으로써 실세계와 비슷한 모델링 가능
- 유지보수의 증진
그럼 이러한 OOP의 특성에 대해 간략하게 알아보겠습니다.
객체지향 프로그래밍의 특성
- 추상화
- 객체들의 공통적인 특징(기능, 속성)을 도출하는 것
- 객체지향적 관점에서는 클래스를 정의하는 것을 추상화라고 할 수 있다.(클래스가 없는 객체지향 언어도 존재 ex.JavaScript)
- 캡슐화(은닉화)
- 실제로 구현되는 부분을 외부에 드러나지 않도록 하여 정보를 은닉할 수 있다.
- 객체가 독립적으로 역할을 할 수 있도록 데이터와 기능을 하나로 묶어 관리하는 것
- 코드가 묶여있어서 오류가 없어 편리하다.
- 데이터를 보이지 않고 외부와 상호작용을 할 때는 메소드를 이용하여 통신을 한다. 보통 라이브러리로 만들어서 업그레이드해 사용할 수 있다.
- 상속성
- 하나의 클래스가 가진 특징(함수, 데이터)을 다른 클래스가 그대로 물려받는 것
- 이미 작성된 클래스를 받아서 새로운 클래스를 생성하는 것
- 기존 코드를 재활용해서 사용함으로써 객체지향 방법의 중요한 기능 중 하나에 속한다.
- 다형성
- 약간 다른 방법으로 동작하는 함수를 동일한 이름으로 호출하는 것
- 동일한 명령의 해석을 연결된 객체에 의존하는 것
- 오버라이딩(Overriding), 오버로딩(Overloading)
- 오버라이딩(Overriding) - 부모클래스의 메소드와 같은 이름을 사용하며 매개변수도 같되 내부 소스를 재정의하는 것
- 오버로딩(Overloading) - 같은 이름의 함수를 여러 개 정의한 후 매개변수를 다르게 하여 같은 이름을 경우에 따라 호출하여 사용하는 것
JVM
JVM(Java Virtual Machine)은 말 그대로 자바 가상 머신입니다.
머신하면 떠오르는 물리적 기계를 자바프로그래밍을 위한 가상 기계로 만들어봤다는 뜻인데, 자바 코드의 실행과 자바 프로그램의 메모리가 이 JVM으로 관리됨으로 자바개발자라면 알아두어야 하는 개념입니다!
JVM의 동작원리는 다음과 같습니다.
여기서 JVM이 개입되기 시작하는건 3번부터라고 봐도 무방합니다. 자바 언어의 특징 중 하나인 것이 바이트 코드로 컴파일 한 것을 OS가 이해할 수 있도록 변환시켜주는 과정 속에서 OS에 구속받지 않고 어느 플랫폼에서도 잘 돌아갈 수 있도록 변환시켜주는 것 입니다.
참고사진
이러한 JVM은 크게 Class Loader, Runtime Data Areas, Execution Engine 3가지로 구성되어 있습니다.
아래의 JVM 개념도를 보면서 각각의 흐름에 대해서 이해하고 역할에 대한 설명을 조금이라도 알 수 있으면 좋겠습니다.
- Class Loader
- RunTime 시점에 클래스를 로딩하게 해주며 클래스의 인스턴스를 생성하면 클래스 로더를 통해 메모리에 로드하게 됩니다.
- Runtime Data Area
- JVM이 프로그램을 수행하기 위해 OS로 부터 별도로 할당 받은 메모리 공간을 말하며, Runtime Data Areas는 크게 5가지 영역으로 나눌 수 있습니다.
사진을 참고하여 보겠습니다.
- Execution Engine
- Load된 Class의 ByteCode를 실행하는 Runtime Module이 바로 Execution Engine입니다. Class Loader를 통해 JVM 내의 Runtime Data Areas 에 배치된 바이트 코드는 Executin Engine에 의해 실행되며, 실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어서 실행합니다.
최초 JVM 이 나왔을 당시에는 Interperter방식(한 줄씩 해석하고 실행)이였기 때문에 속도가 느리다는 단점이 있었지만 JIT complier 방식을 통해 이 점을 보완했습니다. JIT는 ByteCode를 어셈블러 같은 NativeCode로 바꿔서 실행이 빠르지만 역시 변환하는데 비용이 발생합니다. 이 같은 이유 때문에 JVM은 모든 코드를 JIT Compiler 방식으로 실행하지 않고 Interpreter 방식을 사용하다 일정한 기준이 넘어가면 JIT Compiler 방식으로 실행합니다.
참고자료
http://cotylab.com/2020-07-14-oop_concept.html
https://medium.com/@lazysoul/jvm-%EC%9D%B4%EB%9E%80-c142b01571f2
객체지향의 특성
https://asfirstalways.tistory.com/158