항해99 2주차 WIL - 객체지향이란? JVM이란?

Ming-Gry·2022년 10월 2일
2

항해99 WIL

목록 보기
2/12

1) 객체지향 프로그래밍이란?

1-1) 객체지향 프로그래밍이 뭐야?

사실 얼마 전에 객체지향의 사실과 오해라는 책도 읽었지만, 객체지향을 한 마디로 정의하기란 정말 쉽지 않은 것 같다. 그나마 표현해보자면 프로그래밍 패러다임 중 하나로, 데이터를 추상화시켜 속성과 행위를 가진 객체를 만들고 각 객체들의 역할과 책임에 따라 서로 협력하는 관계를 만드는 프로그래밍 정도로 말해볼 수 있겠다. 그냥 저만의 미천한 생각입니다...〒▽〒

1-2) 객체지향의 특징

사진 출처 : https://www.reddit.com/r/ProgrammerHumor/comments/418x95/theory_vs_reality/

위의 사진이 정말 객체 지향의 특징을 잘 설명해주는 사진인 것 같아서 가져와봤다. 객체지향의 특징캡상추다! 캡슐화, 상속성, 추상화, 다형성이다.

캡슐화

사진 출처 : https://radait.tistory.com/5

의학의 발달로 다들 캡슐형 알약은 한 번쯤 섭취해봤을 것이다. 사실 호이포이 캡슐이나 몬스터볼로 개드립을 치고 싶었는데... 캡슐형 알약에는 큰 장점이 있다. 한꺼번에 먹기 어려운 여러가지의 약을 일정한 배합 비율로 한 번에 먹게 해줄 수 있다는 것이다. 환자는 내부 성분과 배합 비율을 신경쓰지 않고 그저 캡슐을 먹기만 하면 된다.

따라서 객체의 캡슐화란, 변수와 함수를 하나의 클래스로 묶고 외부에서 쉽게 접근할 수 없도록 하는 것이다. 이러한 캡슐화는 private, protected 와 같은 접근제어자로 구현 가능하며, 이를 통해 높은 응집도와 낮은 결합도를 가질 수 있다. 응집도와 결합도라는 말이 약간 어려울 수 있는데, 객체 각각은 독립적으로 작용할 수 있도록 응집도가 강해질 수 있고, 다른 한 곳의 변화가 다른 곳에 영향을 미치지 않도록 결합도는 낮아질 수 있다는 뜻이다. 더 어려워졌는데...?

응집도와 결합도에 대한 더 자세한 내용은 아래의 포스팅을 참고하기 바란다.

객체지향 캡슐화, 응집도와 결합도 : https://mangkyu.tistory.com/195

캡슐화 예시

필자가 이렇게 코드를 해괴망측하게 짤 수 있다는 사실에 놀랐다... 이것이 재능...? 결국 필자의 바람대로 포켓몬 세상을 예시로 들어 코드를 짜보았다.

MonsterBall Class 와 Pikachu 객체의 필드를 모두 public 으로 주었더니, capturePikachu() 메소드를 실행할 때 ballName 을 pikachu.leg + ball 을 주어 4ball 이라는 값이 나오고 분명 잡기 전엔 10k였던 Pikachu의 볼트가 MonsterBall 로 잡은 후에는 4k로 변압(?) 되었다!

접근제어자로 캡슐화를 하지 않았더니 각 객체의 독립성이 떨어져 응집도가 약해지고 괴상한 메소드로 인해 결합도 또한 높아져버린 것을 확인할 수 있다.


그래서 MonsterBall Class 와 Pikachu 객체의 필드를 모두 private 으로 바꾸어주었더니 똑똑한 IntelliJ 가 에러를 모두 잡아주었다. private 접근 제어자로 인해 MonsterBall 객체에서 Pikachu 객체에 접근할 수 없다는 것이다! 이로써 MonsterBall 객체는 Pikachu 객체를 필드로 갖고 있지만 Pikachu 객체의 속성을 정의하는 등 과도한 간섭을 하지 않을 수 있으며 MosterBall 객체와 Pikachu 객체는 상호 독립성을 유지할 수 있게 되었다.

수정된 코드는 조금만 더 밑으로 내려보시면 나옵니다!

상속성

캡상추다 때문에 순서가 뭔가 어그러진 것 같다... 상속성은 다형성을 표현하기 위한 하나의 방법으로, 부모 클래스의 성질자식 클래스에게 물려주는 개념으로 말할 수 있다. 상속성을 통해 기존 코드를 재활용 함으로써 코드의 생산성을 높여준다. 그러나 상속은 HAS-A 관계(한 객체가 다른 객체에 속하는 구성관계)가 아닌, IS-A 관계 (자식 클래스가 부모 클래스의 포함관계) 일때와 행동 호환성이 만족하는 경우가 아니면 부작용이 더 많을 수 있으므로 유의해서 사용해야 한다.

이에 대한 포스팅은 아래를 참고하기 바란다.

코드의 재사용, 상속보다 합성을 사용해야 하는 이유 : https://mangkyu.tistory.com/199?category=761303

상속성 예시

포켓몬 세상을 예시로 다시 코드를 짜보았다. ppt 에서 그 피카츄 좀 빼! Pikachu 와 Raichu 모두 전기를 발사할 수 있다는 행동이 호환되고, 모든 라이츄는 피카츄로부터 파생되기 때문에 IS-A 관계가 성립될 수 있기 때문에 상속을 사용했다.

Pikachu 객체를 잡을 수 있는 MonsterBall 은 Pikachu 객체를 상속받은 Raichu 객체를 잡을 수 있게된다. 그러나 Pikachu 객체의 필드를 private 으로 주었기 때문에 이를 상속받은 Raichu 의 voltage 필드는 여전히 10k 로 고정된다는 한계가 있다. 그럼에도 불구하고 전기 공격을 하였을 땐 조물주의 장난으로 Override 로 메소드를 재정의해 100k 볼트를 발사할 수 있게 되었다.

추상화

추상화란 객체들의 공통 특징(기능, 속성)을 추출해서 정의하는 것을 말한다. 추상화의 방법으로는 추상 클래스, 인터페이스를 이용해 공통 특징을 정의한 후 각 클래스에스 구체화해 사용한다. 밑에서 다형성까지 설명한 후에 예시를 한 번에 보도록 하겠다. 기왕 시작한 뇌절...... 끝을 보자......

추상 클래스와 인터페이스에 대한 내용은 아래의 포스팅에 자세히 나와있다.

추상화, 인터페이스, 다형성, 쓰레드, 형변환 : https://velog.io/@alicesykim95/OOP-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A52-%EC%B6%94%EC%83%81%ED%99%94-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EB%8B%A4%ED%98%95%EC%84%B1-%EC%93%B0%EB%A0%88%EB%93%9C-%ED%98%95-%EB%B3%80%ED%99%98#-%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4abstract-class

다형성

다형성이란 하나의 변수 또는 함수가 명령을 받았을 때, 상황에 따라 서로 다른 방식으로 동작하는 것을 말한다. 동일한 명령을 각자 연결된 객체에 의존해서 해석하는 것으로, 오버라이딩이나 오버로딩으로 구현 가능하다.

다형성에 대한 내용은 아래의 포스팅에 자세히 나와있다.

객체지향 프로그래밍이란? : https://velog.io/@khy226/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-OOP-%EC%9D%B4%EB%9E%80#4-%EB%8B%A4%ED%98%95%EC%84%B1-polymorphism

추상화 및 다형성 예시

우선 몬스터볼에 다양한 포켓몬을 넣을 수 있게 Pokemon 객체를 추상클래스로 만들고 이를 MonsterBall의 필드로 선언하였다.

모든 포켓몬의 공통인 이름과 꼬리의 길이(?) 그냥 그렇다 치자...필드로 선언했고, 어떤 포켓몬이 됐든 그 이름과 꼬리의 길이 알 수 있도록 getter Method 또한 선언해주었다. 포켓몬의 공격 기능을 정의하기 위해 Attack 인터페이스 또한 만들었다. 이로써 포켓몬 객체를 만들기 위한 추상화 설계는 얼추 마무리 되었다.

이렇게 만들어진 추상 클래스 Pokemon 과 인터페이스를 Pichu 에 상속 및 구현하여 Pichu 클래스에 생명을 불어 넣어줬다. 다만 Pichu 의 고유 특성이라고 할 수 있는 voltage 는 따로 필드로 선언생성자에서 그 값을 줄 수 있도록 하였다. 또한 Pichu 는 최하위 포켓몬이므로 attack Method 만 구체화하고, 나머지 tailPress와 thunderStorm Method 는 구체화하지 않았다.

Pikachu 객체는 Pichu 를 상속받고, Raichu 객체는 Pikachu 객체를 상속받아 그 속성을 이어받되, 각각 tailPress Method 와 thunderStorm Method 를 구체화해 각 객체 별로 다른 기능이 구현되도록 하였다.

이거 보여주려고 어그로 끌었다... MonsterBall 객체를 만들고, Pichu 객체를 생성해 Attack Interface 의 모든 Method 를 Override 했다. 그러나 Pichu 객체에서는 attack() 만 재정의했기 때문에 나머지 Method 에서는 null 이 출력되었다.

그 이후에 Pichu 객체를 Pikachu 객체로 타입 변환하였다. Pichu 객체가 Pikachu 객체의 상위 클래스이기 때문에 형변환에 아무런 문제가 없고, Pichu 객체에서 implement 받았던 모든 Method 들도 정상 작동한다. 그러나, Pikachu 객체에서는 tailPress() 만 재정의하고, thunderStorm() 을 재정의 하지 않았기 때문에 null 이 출력되었다.

Pikachu 객체를 Raichu 로 변환해도 위의 상황과 같다. 다만 상속을 이어오며 모든 Method 를 재정의했기 때문에 모든 메소드에서 입력된 값이 출력된다.

그 이후에 Raichu 객체를 MonsterBall 객체의 getPokemon() 으로 납치해왔다. Monsterball 안에 있는 Pokemon 객체는 움직일 수 없으므로(추상클래스이므로), 이름을 보거나 꼬리의 길이만 확인할 수 있다.

마지막으로 몬스터볼에서 포켓몬을 꺼냈다. 재밌게도 포켓몬 세상에서는 힘과 속성은 그대로지만 외형은 귀여운 피츄나 피카츄의 모습으로 꺼낼 수 있다. 따라서 Pichu 객체로 형변환을 해 가져온 후 Method 를 실행시켜보니 외형은 Pichu 이지만 Raichu로 재정의된 필드값을 갖고 재정의된 Method 대로 출력되는 것을 볼 수 있다.

MonsterBall 객체에서 Pokemon 이라는 추상 클래스를 사용한 덕분에 캡슐화가 가능했고(MonsterBall 객체에서 Pokemon 의 구체 클래스 타입은 알 수 있으나 객체를 직접 불러오는 등의 행위가 불가능하다.), 이를 상속시켜 하위 클래스들에서 구체화시킬 수 있었다. 이를 통해 형변환으로 다형성이 구현 가능했다. 또한 Interface 의 Method 를 각 객체에서 재정의 함으로써 다형성을 갖출 수 있었다.

이 정도면 캡슐화, 상속성, 추상화와 다형성이 골고루 짜인 아주 적절한 예시가 되지 않았을까 싶다. 진심으로 바래본다... 여기까지 공부하고 자료찾고 포켓몬 세상 다시 공부하고... 코드짜고 블로그 적고 6시간은 걸린 것 같다...

1-3) 객체지향의 장단점

객체지향의 장점

  • 코드 재사용이 용이함

    모듈화된 객체, 그리고 상속을 통해 코드의 재사용을 높일 수 있다.

  • 생산성이 향상됨

    독립적인 객체를 사용함으로써 개발의 생산성을 향상시킬 수 있다. 이미 생성된 클래스를 상속받거나, 객체를 재사용, 부분 수정 등 적은 노력으로 높은 효율을 만들어낸다.

  • 자연적인 모델링 가능

    현실세계에서 사용하는 개념을 대입하여, 생각한 것을 그대로 구현할 수 있다.

  • 유지보수가 쉬움

    프로그램 추가, 수정 시 캡슐화를 통해 주변에 미치는 영향을 제한할 수 있다.

객체지향의 단점

  • 실행 속도가 느림

    객체 지향 프로그래밍은 캡슐화와 격리 구조 때문에 절차 지향 프로그래밍에 비해 실행 속도가 느리다.

  • 상대적으로 큰 용량이 필요하다

    객체 단위로 프로그램을 많이 만들다보면, 불필요한 정보들이 들어가 이것이 프로그램의 용량을 증가시킬 수 있다.

  • 개발 속도가 느림

    객체가 처리하려는 것에 대해 정확하게 파악해야 하므로, 설계 단계에서 많은 시간과 노력이 필요하다.

출처 : https://velog.io/@khy226/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-OOP-%EC%9D%B4%EB%9E%80#%EC%9E%A5%EC%A0%90

1-4) SOLID 원칙

사실 객체지향 프로그래밍의 꽃인 SOLID 원칙 또한 쓰고 싶지만... 어그로 끄느라 너무 많은 힘을 썼나봅니다... 다음 포스팅으로 넘기겠습니다... 언젠가 저의 링크를 거는 날이 오겠죠?ಥ_ಥ

객체지향 설계 5원칙 - SOLID 란 무엇일까? : https://devlog-wjdrbs96.tistory.com/380

2) JVM이란?

JVM도 이거 잘못파면 엄청 내용이 깊어질 것 같아 이번 포스팅에서는 혼자 공부하는 Java 라는 책의 일부를 참고하여 간단히 다음 포스팅에 더 자세히 쓰겠습니다...!! 읍!!! 읍!!!!!!

JVM 은 Java Virtual Machine 의 약자로, 자바 프로그램 실행환경을 만들어 주는 소프트웨어입니다. 자바 코드를 컴파일하여 바이트 코드로 만들면 이 코드가 자바 가상 머신 환경에서 실행됩니다. JVM 을 사용하면 하나의 바이트코드로 각자의 플랫폼에 설치되어 있는 JVM이 운영체제에 맞는 실행 파일로 바꿔 어떤 운영체제에서도 동작하도록 할 수 있습니다.

profile
항상 진심이지만 뭔가 안풀리는 개발 (주의! - 코린이가 배우고 이해한 내용을 끄적이는 공간이므로 실제 개념과 일부 다를 수 있음!)

0개의 댓글