본문 바로가기

취미로 하는 게임코딩_gameCodingAsHobby/유니티unity로 게임 만들기

유니티16_C#_09_캡슐화

앞 글에서 객체 지향 언어(OOP)의 출발점인 추상화로 클래스와 객체를 만들어 보았다.

이번에는 객체지향 언어의 클래스를 떠 받치고 있는 3개의 핵심 개념에 대해 알아본다.

 

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

1. 캡슐화(Encapsulation)

캡슐화는 데이터를 캡슐에 넣는다는 뜻이다.

 

유산균을 캡슐에 넣은 제품이 기억난다.

유산균을 위산으로 부터 보호해서 죽지 않고 대장까지 가도록 캡슐화한 것이다.

코딩에서 캡슐화도 '묶음'과 '보호'라는 역할을 담당하기 위해 고안되었다.

 

캡슐화의 목적은 2가지이다.

 

1. 멤버(필드, 메서드)를 하나의 단위로 묶는다

2. 멤버(필드, 메서드)를 보호한다.

 

즉, 멤버를 묶어서 보호하는 것이 캡슐화의 목적이다.

데이터를 묶어서 관리하면 코드를 읽기 쉽고 수정할 때도 편리하다.

데이터를 보호해야 하는 이유는 데이터를 노출하지 않기 위해서 이거나 다른 사람에 의해 코드가 수정되거나 훼손되는 것을 막기 위해서이다.

 

하나의 단위로 묶는데 사용하는 캡슐은 주로 클래스(class)를 사용한다.

다시 말해서 객체 지향 언어에서는 클래스라는 캡슐(금고)에 관련된 필드와 메서드를 모아서 정의한다. 

그리고 클래스 캡슐(금고)를 지키기 위해서 4가지 등급으로 된 접근제한자(Access Modifier)라는 열쇠(Key)를 만들었다.

 

1.1 접근 제한자(Access Modifier)

접근제한자는 클래스 외부에 멤버를 공개할 것인지, 공개하지 않을 것인지 혹은 공개한다면 어디까지 공개할 것인지를 결정하는 키(열쇠)다.

 

접근 제한자는 다음과 같은 것들이 있다.

 

  • public (공공을 위한) : 같은 어셈블리 또는 참조하고 있는 다른 어셈블리에서 접근이 가능하도록 공개한다
  • internal (내부의) : 같은 어셈블리 안에서만 접근이 가능하다.
  • protected (보호된) : 같은 클래스 또는 해당 클래스에서 상속된 클래스에서만 접근이 가능하다.
  • private (개인 전용의) : 같은 클래스 안에서만 접근이 가능하다. 

 

*참고: C# 언어에서는 완성하여 배포하는 하나의 프로그램을 Assembly(어셈블리)라고 부른다.

 

접근제한자는 클래스 이름이나 멤버의 제일 앞에 붙이지만 생략할 수 있다.

하지만 생략하면 클래스는 internal로 , 멤버(필드와 메서드)는 private으로 설정된다.

 

그런데 데이터 보호를 위해 접근제한자로 접근을 막아 놓았지만 경우에 따라 데이터를 읽거나 수정해야 할 상황이 생길 수도 있다. 이런 상황에 대처할 수 있도록 필드에 안전하고 유연하게 접근하게 하는 Property(프라퍼티; 속성)라는 것을 만들어 두었다.

 

1.2 Property(프라퍼티; 속성)

Property는 클래스의 필드에 접근하기 위한 특수한 메서드이다.

Property는 접근자(Accessors)라고 불린다.

Property의 역할은 private으로 접근 제한된 필드 값을 읽거나 설정할 수 있게 한다. 

 

접근자(Accessor)는 2개 있다.

 

get

set

 

Property를 정의하는 형식은 다음과 같다.

 

접근제한자   타입   프라퍼티명

{

    get

    {

        return 필드명;

    }

 

    set

    {

        필드명 = value;

    }

}

 

get 메서드는 특정 필드의 값에 접근할 때 실행되고

set 메서드는 특정 필드의 값을 변경할 때 실행된다.

그러므로 get 메서드가 없으면 private으로 설정된 필드값에 접근할 수 없고

set 메서드가 없으면 private으로 설정된 필드값을 수정할 수 없다.

 

예를 들어 앞에서 만든 MainCharacter클래스를 이용하여 프라프티를 만들면 다음과 같다.

 

17번줄에 MainCharacter라는 클래스를 정의하고

3번줄에 PropertyExample이라는 클래스가 정의되어 있다.

 

19~20번줄

필드 name, age는 private으로 접근 제한되어 있다.

 

22번줄~32번줄

필드 name과 age의 프라퍼티를 각각 Name , Age 라는 이름으로 정의했다.

프라퍼티 이름은 첫글자만 대문자로 해서 같은 이름으로 했지만 원하는 이름으로 지을 수 있다.

단 get, set 메서드 안에만 필드명을 정확하게 지정하면 된다.

 

7번줄

Tom이라는 객체를 생성했다.

 

9번줄

객체의 이름을 확인하기 위해 nameTest라는 변수를 만들었다.

객체 Tom의 이름 값(value)에 접근하기 위해 Name 프라퍼티를 사용한다. 

Name 프라퍼티를 호출하면 get 메서드에 정의된 대로 Tom객체의 name필드값을 가져와서 반환한다.

결국 변수 nameTest에는 Tom의 name값이 저장된다.

 

10번줄

객체 Tom의 Age 프라퍼티에 값(value) 55를 저장하라는 코드이다.

value(값)을 변경하는 것이므로 프라퍼티의 set메서드가 실행된다.

set의 value에 55가 저장된다.

이 값이 다시 age필드에 저장된다.

결국 Tom객체의 age값이 55로 변경된다.

 

유니티에서 코드 확인

 

이제 위 코드를 유니티에서 실행해서 결과가 어떻게 나오는지 확인해 보자.

먼저 PropertyExample.cs 스크립트를 Ctrl+S를 눌러서 저장한다.

 

 

유니티에서 프로젝트를 만들고 GameObject(게임 오브젝트)를 하나 만든다. (기존에 연습하던 프로젝트로 테스트 해도 상관없다.)

 

Assets에서 마우스 오른쪽 버튼을 누른 후 Import New Asset (새 에셋 불러오기)를 클릭한다.

Scripts폴더를 만들었다면 그 곳에 Import하면 된다.

 

탐색기 창에서 테스트할 스크립트를 선택한 후 Import 버튼을 클릭한다.

 

Assets 폴더에 스크립트가 추가된다.

참고로 이렇게 테스트할 스크립트를 추가할 때는 Assets폴더에 같은 클래스를 가진 다른 스크립트가 있다면 삭제한 후에 추가해야 한다.

 

Hierararchy창에서 GameObject를 선택한 후 Inspector창에서 Add Component버튼을 클릭한다.

검색창에 pro~정도만 입력하면 Assets폴더에 등록해 놓은 스크립트 파일을 찾을 수 있다.

Property Example을 클릭하면 컴퍼넌트가 추가된다.

 

Property Example 스크립트가 체크된 것을 확인한 후 실행버튼을 누른다.

 

콘솔(Console)창에 결과가 나타나는 것을 확인한다.

 

 

위와 같이 객체 생성을 위해 클래스를 정의한 후, 필드에 대해 프라퍼티(속성)를 정의하여 외부 클래스에서 프라퍼티를 이용해서 필드에 접근하거나 값을 바꿀 수 있는 코드 구조를 만들었다.

객체 지향 언어에서 코드를 작성할 때에는 지금까지 살펴본 캡슐화를 적용해야만 잘 짜여진 코드라고 할 수 있다.

 

다음 글에서는 클래스 구조의 또 다른 핵심인 상속에 대해 알아본다.

 

끝.

Wraven...