unity 기본12 - scope, 캡슐화, getter, setter, public, private, protected

1. for문

 

for문을 만들고, for문 내부에 x = 2;를 선언

 

for문 밖에서 x를 출력해본다면?

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HelloWorld : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        for (int i = 0; i < 10; i++)
        {
            int x = 2;
            Debug.Log(i);
        }

        Debug.Log(x);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

 

for문 밖의 x에 빨간줄이 그어지는데

 

for문 내에서 만든 변수는 밖에서 쓸 수 없다

 

 

 

 

 

마찬가지로 for문 initializer에서 만든 i도 밖에서 쓸 수 없다

 

 

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------

 

for문보다 먼저 int x = 4;를 선언하고 for문 내에서 int x = 2;를 선언하면?

 

에러가 난다

 

 

 

 

이미 x = 4;가 있으니까 에러나는건가? 그렇게 생각해서 for문 뒤에 int x = 4;를 한다면?

 

그래도 에러가 난다

 

이건 좀 신기한데

 

 

 

 

2. 사용자 정의 함수

 

어떤 함수 내에서 만든 int x = 2;와 Start() 함수 내에서 만든 int x = 4;는 다른거라 에러가 나지 않는다

 

Hamsu() 내의 int x = 2;를 아무리 바꿔도, Start() 내의 int x = 4;에는 영향을 미치지 않는다

 

 

 

 

 

3. class의 멤버변수

 

HelloWorld class의 멤버변수로 int x;를 만들더라도, 내부 method내에 int x를 선언해도 에러나지 않는다

 

내부 method에서 만든 x와 멤버변수 x는 서로 다르다

 

 

 

 

method내에서 멤버변수 x에 접근하고 싶으면 this.x로 접근

 

 

 

 

 

4. 캡슐화

 

객체를 통해 프로그램 내에서 구현했을 때 밖에서 보여야 하는 것은 보이는 게 좋고 보일 필요가 없는 것은 안보이는 것이 좋다

 

객체: 인간

 

method: 먹는다

 

먹는다라는 기능을 구현하고자 할 때, 입에 넣는다 > 씹는다 > 삼킨다 > 식도를 지나친다 > 위장 > 소장 > 대장 > ...

 

이러한 과정을 밖에서 일일이 알 필요는 없다

 

쓸데없는 것이 많이 보이면 혼란스러울 뿐

 

객체가 캡슐이 되어 내부에 뭐가 들어있는지 신경쓰지 않아도, 내부의 내용을 다 가져다 쓸 수 있는 것

 

먹는다라는 결과만 보이면 된다

 

public : 누구나 다 볼 수 있는 내용

 

protected : public과 private의 중간쯤... 외부에서는 모르지만 자식 클래스는 아는 내용

 

private: 밖에서 볼 수 없는 것(자식 클래스도 모름)

 

아무것도 설정하지 않으면, C#은 기본적으로 private으로 설정함

 

 

5. 캡슐화 예시

 

설정하지 않은 멤버변수 name, hp는 기본값 private

 

method들이나 class 앞에 public으로 설정

 

public이기 때문에 class 밖에서 method들을 호출할 수 있음

 

만약 method앞에 private으로 설정하면 밖에서 method를 호출할 수 없음

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Character
{
    string names;
    int hp;

    public Character()
    {

    }

    public Character(string characterName, int initialHP)
    {
        names = characterName;
        hp = initialHP;

    }

    public void Hit(int damage)
    {
        hp -= damage;
    }

    public void Heal(int heal)
    {
        hp += heal;
    }

    public bool isAlive()
    {
        return hp > 0;
    }

    public void Eat(Food food)
    {
        if (isAlive())
        {
            hp += food.hp;
        }
    }
}

 

 

 

private은 자식 클래스도 호출불가능함

 

 

 

 

만약 멤버변수를 public int hp;로 설정하면?

 

 

 

 

자식 클래스에서 에러나지 않는다

 

 

 

 

 

HellowWorld에서 Character instance를 만들고, hp에 접근하면 접근이 가능하고 값을 집어 넣을 수도 있지만

 

private인 names에는 접근 불가

 

 

 

 

멤버변수 hp를 protected로 바꾼다면?

 

 

 

 

HelloWorld인 완전 외부에서는 hp에 접근 불가

 

 

 

 

하지만 private와는 다르게 자식 클래스 Wizard에서는 hp에 접근할 수 있다

 

 

 

 

이런 보호수준을 지정하는 이유는 마음대로 누군가가 바꾸는 것을 방지하기 위함

 

무작정 public으로 해버리면 코드가 복잡해질 수록 꼬여서 고치기 힘들어질 수 있다

 

 

6. getter & setter

 

getter은 값을 get하는 곳이고 setter은 값을 set하는 곳

 

외부에서 보호중인 멤버변수에 접근하고자 할 때, 한 곳에서만 접근할 수 있게 만들어 준다

 

Character class의 hp를 private으로 바꾸고

 

 

 

 

 

외부에서 hp에 값을 넣고 싶다면?

 

단순히 접근하면 불가능함

 

 

 

 

다음과 같이 GetHp()와 SetHP(hp)를 정의

 

GetHP()는 현재 멤버변수 hp를 return

 

SetHP(hp)는 hp를 받아 멤버변수 hp를 parameter로 받은 hp로 설정

 

 

 

 

이 method들은 public이라 외부에서 접근 가능한데, 

 

이제 이 method들을 통해서 Character의 멤버변수를 바꿀 수 있다

 

 

 

 

그냥 멤버변수를 public으로 설정하고 raiden.hp = 10;으로 바꾸는게 편하지 않나?

 

하지만 이렇게 setter, getter를 설정하면...

 

1) 예를 들어 hp를 설정할 때 어떤 처리 (mp도 초기화된다든지)해야한다면 setter안에 그러한 처리도 설정해줘서

 

코드 관리가 편하다

 

그리고 2) 값을 접근할 수는 있지만 변경할 수는 없게 하고 싶다면 getter만 남기고, setter은 지우면 된다

 

----------------------------------------------------------------------------------------------------------------------------------------------------

 

 

7. get & set

 

이런 getter와 setter은 많이 쓰이다 보니.. 편하게 만드는 방법이 있다

 

public int hp

{

get; set;

}

 

 

 

 

얘를 사용하는 방법? raiden.hp = 10;으로 setter를 사용할 수 있는데...

 

 

 

 

이러면 public이랑 똑같은거 아닌가?

 

하지만 set;을 지운다면?

 

 

 

 

setting이 불가능해진다

 

 

 

 

하지만 raiden.hp에 접근은 가능함

 

 

 

 

이렇게 만들때도, 다음과 같이 get, set 내부에 원하는 기능을 추가할 수 있긴 있다

 

public int hp;

{

get

{

return hp;

}

}

 

 

 

 

set의 매개변수는 value로 고정되어있는듯? 다른거 쓰면 에러남

 

-------------------------------------------------------------------------------------------------------------------------------------------

 

다른 방법으로는 다음과 같이 private int hp; public int HP; 2가지 변수를 설정하고

 

HP 내부에 hp와 관련된 get, set을 설정

 

 

 

 

이렇게 하면 실제 hp 변수는 hp지만, 외부에서 hp에 접근하고 싶으면 HP를 이용해서 접근해야한다

 

 

 

 

TAGS.

Comments