본문 바로가기

C++

([C++] 28강) 객체지향(OOP)의 4대 기본원칙 중 캡슐화

안녕하세요 잭클입니다.

 

이번시간에는 객체지향프로그래밍(OOP)의 4대 기본원칙이라고 부르는 개념들과

 

그중에서 한가지인 캡슐화를 배워보도록 할건데요!

 

"기본원칙" 이라고 부르는 만큼 매우매우 중요한 개념이니 꼭꼭 외워두시길 바랍니다!

 

 

 

 

객체지향의 4대 기본원칙은 아래와 같습니다.

 

  • 추상화(Abstraction)
  • 캡슐화(Encapsulation)
  • 상속(Inheritance)
  • 다형성(Polymorphism)

이 중 우리는 오늘 캡슐화에 대해서 배워보도록 하겠습니다.

 

 

 

우선 이해하기 쉽기 위해서 캡슐화 라는 이름 가지고 예시를 들어보도록 하겠습니다.

 

"캡슐" 하면 뭐가 생각나시나요?

 

뭐 뽑기 캡슐이 생각날수도있겠지만, 설명을 위해 저는 알약 캡슐로 예시를 들어보겠습니다.

 

자, 우리는 감기에 걸려서 종합 감기약을 먹어야합니다.

 

종합감기약을 뜯어서 캡슐알약을 하나 꺼냈어요,

 

우리의 눈에는 1개의 캡슐 알약일 뿐이지만

 

자세히는 과연 1개일까요?

 

캡슐을 열어서 안에 들어있는 약물들을 분석해보면

 

코감기약 목감기약 해열제 등등 꽤나 많은 성분들이 들어있을것 같지않나요?

 

캡슐화란 바로 이런겁니다! 한가지를 위해서 그것에 필요한 요소들을 담아내는것

 

예를들자면

 

자동차 안에 엔진, 바퀴, 차체가 있는것도 일종의 "캡슐화" 이고

 

사람이라는 정보 안에는 이름, 나이, 성별, 전화번호 라는 정보가 들어있는것도 "캡슐화" 입니다.

 

이해 되셨나요?

 

 

 

 

 

 

우리는 저번시간에 클래스에 대해서 배웠습니다.

 

하지만 클래스 안은 비어있는 상태였고 이는

 

빈 껍데기 상태의 "캡슐껍데기" 와 같다고 보면 됩니다.

 

이제 그 안을 구성하는 요소들을 넣어볼겁니다.

 

본격적으로 프로그래밍으로써의 캡슐화를 보도록 하죠!

 

저번시간에 만들었던 People 클래스, 즉 사람정보 안에 들어갈 내용들은 무엇이 있을까요?

 

우리는 오늘 이름, 나이, 성별에 대한 정보와

 

인사를 하도록 하는 함수를 추가해 보도록 하겠습니다.

 

 

using namespace std;

class People {
public:
    char* name;
    bool isWoman = false;
    int age = 1;

    void SayHi() {
        cout << "안녕하세요 저는 " << this->name << "입니다. 나이는 " << this->age << "살입니다" << endl;
    }
};

정말 간단하죠??

 

class People 라는 구절의 중괄호 안에 코드를 넣어주면

 

People라는 클래스가 가진 정보를 선언하는것이 됩니다.

 

그런데 여기서 헷갈리는것들이 몇가지 있네요!

 

public: 이건 또 뭐고

 

this는 또 뭐고

 

-> 이건 또 뭘까요?

 

public은 접근제어지시자 라는것인데, 다음시간에 배울 내용이니 이번 시간에는

 

그냥 따라쓰는것으로 해봅시다!

 

 

 

그럼 this는 뭘까요! 네 맞습니다! this! 이것!

 

바로 자신을 가리키는 변수입니다. 따로 선언하지 않아도 기본적으로 존재하고

 

자료형은 People * (피플 포인터) 형입니다!

 

 

 

그렇다면 -> 이것은 딱 보면 알겠죠? this->name이니

 

내 안에 있는 이름!

 

즉 "?? 안에 있는 ??"  와 같습니다!

 

하지만 이 내용에 대해선 추가적으로 설명할 것이 있으니, 이 글 마지막 부분에 설명하도록 하겠습니다!

 

 

하지만  this를 안붙여도 사실은 괜찮습니다!

 

this를 붙이지 않고 없는 변수를 사용하면, 자동으로 클래스 내에 해당 변수가 있는지 검사하고 사용합니다!

 

그럼 this는 언제 사용해야할까요?

 

아래 예제를 보시죠

 

class People {
public:
    int age = 0;    

    void SetNewAge(int age) {
         age = age;
    }
}

SetNewAge라는 함수를 만들었습니다! 새로운 나이를 현재 나이에 덮어 씌우는 코드를 원하고 짠건데

 

이렇게하면 어떻게 될까요?

 

SetNewAge에서 this가 없는 age는 매개변수로 받은 age로 판단합니다.

 

따라서 매개변수로 받은 age를  People안의 age에 할당하려면

 

this를 붙여서 this->age로 바꿔주던가 SetNewAge의 매개변수의 이름을 바꿔주면 됩니다!

 

class People {
public:
    int age = 0;    

    void SetNewAge(int age) {
         this->age = age;
    }
}

//또는

class People {
public:
    int age = 0;    

    void SetNewAge(int newAge) {
         age = newAge;
    }
}

이렇게 말이죠!

 

아래는 매개변수의 이름이 age가 아닌 newAge로 바뀌었기때문에

 

this가 안붙은 age가 클래스 안의 age를 가리키게 되기때문에

 

자동으로 클래스 안의 age에 매개변수 newAge가 할당되게 되는겁니다

 

이해 하셨나요??

 

 

 

 

자 그럼 클래스를 짰으니 메인함수도 추가해볼까요?

 

#include <iostream>
using namespace std;

class People {
public:
    char* name;
    bool isWoman = false;
    int age = 1;

    void SayHi() {
        cout << "안녕하세요 저는 " << this->name << "입니다. 나이는 " << this->age << "살입니다" << endl;
    }
};

void main() {
    People jeckl;
    People gildong;

    char name[100] = "잭클";
    char name2[100] = "홍길동";
    jeckl.name = name;
    gildong.name = name2;
    jeckl.age = 23;
    gildong.age = 100;
    jeckl.SayHi();
    gildong.SayHi();
}

메인 함수의 내용만 한번 보겠습니다!

 

People형 변수 jeckl과 gildong을 만듭니다!

 

문자열 name1과 name2를 만들고 각각 잭클과 홍길동 이라고 써준후에

 

jeckl과 gildong 안의 name에 할당해줍니다!

 

jeckl과 gildong의 나이에 각각 23과 100살이라고 정보를 넣어주고

 

jeckl에게 인사를 하라고 시킵니다!

 

gildong한테도 인사를하라고 시킵니다!

 

자 한번 실행시켜볼까요??

 

생각 했던 대로 인사까지 잘 하네요!

 

 

 

그런데 헷갈리는 부분이 또 있죠!

 

왜 여기선 "?? 안에있는 ??" 이 ->가 아니고 .일까요?

 

.과 ->의 차이가 헷갈릴텐데요!

 

한트를 드리자면 jeckl과 gildong은 People형이고

this는 People * 형이라는 겁니다!

 

눈치 채셨나요??

 

바로 포인터입니다!

 

기본적으로는 객체의 요소에 접근할때는 .을 사용합니다

 

a.b (a 안에있는 b) 처럼 말이죠

 

하지만 a가 포인터라면, 우리는 포인터의 값 부분에 접근해서 요소를 가져와야 한다는것을

 

기억할겁니다. 기억 못한다면 꼭꼭꼭 포인터에 대해서 다시 공부하고오세요! 필수입니다!

 

 

([C언어] 15강) 포인터와 어드레스연산자

와.. 여기까지 오신 여러분 수고 많으셨습니다. 이제부터 C언어에서 가장 어려운 개념인 포인터에 대해 공부할건데요 (솔직히 진심으로 포인터 강좌하기 싫어서 내일할까 하고 미루려다가 한번

jeckl.tistory.com

 

자 그럼 우리는 a가 People *형의 변수고 a의 값 안에 있는 b를 가져오려면 어떻게 해야할까요?

 

(*a).b 이렇게 해주어야합니다!

 

벌써 가독성이 떨어지지 않나요?

 

바로 이것을 생략하고 "?? 주소의 값부분 안에 있는 ??" 이 바로 ->연산자 인것입니다.

 

만약에 jeckl과 gildong변수가 People형이 아닌 People * 형이었다면

 

(*jeckl).name 혹은 jeckl->name 이렇게 접근해야하는것이죠!

 

뭐가 더 보기 편한가요! 당연히 jeckl->name이겠죠!

 

이해 되셨나요??

 

 

 

 

 

 

자 그럼 이번시간에는 객체지향프로그래밍(OOP)의 4대 기본원칙 중 하나인 캡슐화에 대해서 배워보았습니다!

 

다음시간에 만나요!