달나라 노트

C# : field와 property (get, set, Access Modifier) 본문

C#/C#

C# : field와 property (get, set, Access Modifier)

CosmosProject 2022. 3. 23. 18:55
728x90
반응형

 

 

 

class 관련 내용 얘기를 할 때 Access Modifier에 대해 얘기를 했습니다.

 

Access Modifier 관련 내용

https://cosmosproject.tistory.com/543

https://www.w3schools.com/cs/cs_access_modifiers.php

 

C# Access Modifiers

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

 

 

요약하자면 다음과 같습니다.

 

class 안에서 private 키워드와 함께 선언된 변수는 다른 객체에서 사용할 수 없다.

class 안에서 public키워드와 함께 선언된 변수는 다른 객체에서 사용할 수 있다.

 

이렇게 Access Modifier 기능이 있는 이유는 여러 가지가 있겠지만 그 중 하나의 이유를 꼽아보자면 class의 보존입니다.

class 내부의 여러 속성값들을 private으로 설정해두면 원본 class를 처음에 개발자가 의도한 그대로 유지시킬 수 있으며 어딘가에서 원본 class에 있는 어떠한 속성값을 변경한다던지 등의 에러가 발생하지 않을겁니다.

 

근데 사용하다면 private으로 선언된 속성값을 조회해야할 때가 있습니다.

아무리 원본 class의 내용을 보존한다고 해도 원본 class의 속성값을 절대 조회하지 못한다는건 사실 프로그래밍을 하는 의미가 없으니까요.

 

private으로 선언된 속성값들에 접근하기 위해서 사용할 수 있는 방법은 class에 속성값에 접근할 수 있게 해주는 method를 선언해서 사용하는 것입니다.

 

아래 예시를 보시죠.

 

using System;

class Monster
{
    private int hp = 100;
    private int mp = 100;

    public void set_hp(int hp)
    {
        this.hp = hp;
    }

    public void set_mp(int mp)
    {
        this.mp = mp;
    }

    public int get_hp()
    {
        return this.hp;
    }

    public int get_mp()
    {
        return this.mp;
    }
}

class MyProgram
{
    static void Main()
    {
        Monster golem = new Monster();

        golem.set_hp(1000);
        golem.set_mp(300);

        Console.WriteLine(golem.get_hp());
        Console.WriteLine(golem.get_mp());
    }
}


-- Result
1000
300

위 예시는 hp, mp를 private으로 설정해두고 Monster class 내부에서 hp, mp값을 설정하거나 얻어올 수 있는 method를 별도로 설정해둔 예시입니다.

 

위 예시에서 hp, mp값은 Monster class에서 분명히 private으로 설정되어있음에도 불구하고 Main method에서 golem class를 설정했을 때 hp, mp값을 변경하기도하고 hp, mp값을 얻어와 출력하기도 합니다.

 

이게 가능한 이유는 Monster class에서 hp, mp 속성값을 우회적으로 설정하거나 우회적으로 hp, mp값을 얻어올 수 있도록 하는 method들 (set_hp, set_mp, get_hp, get_mp)을 만들어뒀기 때문입니다.

 

 

사실 이처럼 해도 큰 문제는 없습니다. 좋은 방법이죠.

근데 좀 귀찮습니다.

 

매번 모든 class에 있는 속성값들을 private으로 선언해두고 그 값들마다 값을 재설정하고 값을 얻어오는 method를 설정하는것은 상당히 번거로울거예요.

 

 

이럴 때 사용하는 것이 property입니다.

 

아래 예시는 위에서 봤던 코드를 동일한 기능을 가진 채로 프로퍼티를 이용하도록 변경한 것입니다.

using System;

class Monster
{
    private int hp = 100;
    private int mp = 100;

    public int Hp
    {
        set { hp = value; }
        get { return hp; }
    }

    public int Mp
    {
        set { mp = value; }
        get { return mp; }
    }
}

class MyProgram
{
    static void Main()
    {
        Monster golem = new Monster();

        golem.Hp = 1000;
        golem.Mp = 300;

        Console.WriteLine(golem.Hp);
        Console.WriteLine(golem.Mp);
    }
}


-- Result
1000
300

위 코드를 보면 Monster class에서 Hp, Mp라는 public 변수를 따로 설정하고 있고 set, get을 이용한 부분이 추가되었습니다.

 

그리고 Main method에서 보니 golem 객체를 만들고, Hp, Mp값에 접근하여 Hp, Mp값을 변경하거나 Hp, Mp값을 가져오고 있습니다.

 

이렇게 set, get을 이용하면 class의 private 속성값을 우회적으로 불러와서 golem.Hp, golem.Mp 등과 같이 마침표(.)로 구분하여 Hp, Mp값을 마치 class의 프로퍼티 중 하나인 것 처럼 사용할 수 있도록 해줍니다.

 

 

이에 대해 자세히 살펴봅시다.

 

class Monster
{
    private int hp = 100;
    private int mp = 100;

    public int Hp
    {
        set { hp = value; }
        get { return hp; }
    }

    public int Mp
    {
        set { mp = value; }
        get { return mp; }
    }
}

먼저 Monster class 선언 부분을 봅시다.

 

hp, mp 변수를 private으로 설정하는 것은 동일합니다만, Hp, Mp라는 변수를 public으로 선언하는 것이 추가되었습니다.

hp와 Hp는 H가 각각 소문자와 대문자로 다른 변수입니다.

 

그리고 Hp, Mp 변수는 각각 get, set이라는 내용을 가지고있죠.

 

 

 

 

...
    private int hp = 100;

    public int Hp
    {
        set { hp = value; }
        get { return hp; }
    }
...

hp, Hp 변수만 따로 봐봅시다.

 

우리의 목적은 private으로 선언된 hp 변수의 값 자체에는 접근을 막으면서 hp라는 속성값은 이용할 수 있도록 하는것입니다.

 

이를 위해서 Hp라는 변수를 public으로 선언하고 set, get 기능을 사용하여 Hp를 Monster class의 프로퍼티가 되도록 만든 것입니다.

 

일단 위처럼 선언하면 우리는 class의 hp는 여전히 이용할 수 없지만 아래와 같이 Hp는 이용할 수 있습니다.

 

        Monster golem = new Monster();

        golem.Hp = 1000;

마치 Hp가 golem이라는 객체의 프로퍼티 중 하나인 것처럼 사용이 가능한것이죠.

 

 

이것을 가능하게 해주는 것이 set, get입니다.

 

...
    private int hp = 100;

    public int Hp
    {
        set { hp = value; }
        get { return hp; }
    }
...

다시 set, get 부분을 봅시다.

 

- set { hp = value; }

set은 hp값을 새로운 값을 할당하도록 해줍니다.

golem.Hp = 1000; 등과 같은 코드가 적혔을 때 새로운 hp값을 할당해주는 것이죠.

여기서 1000과 같이 할당할 값을 value라고 칭합니다. (할당할 값을 value라고 칭하는 것은 약속이기 때문에 value라고 써야만 합니다.)

 

따라서 Hp라는 프로퍼티에 1000이라는 value를 할당하면 Hp 프로퍼티는 이것을 value로 받아 hp 변수에 할당하는 것이죠.

그러면 private으로 선언된 hp값은 전혀 건드리지 않고 hp값을 원하는 값으로 할당하였습니다.

 

- get { return hp; }

get은 hp값을 return해줍니다.

Console.WriteLine(golem.Hp); 등과 같은 코드가 적혔을 때 hp값을 return해주죠.

그래서 get 구문을 보면 return hp라고 적혀있습니다.

 

실제 객체를 사용할 때에는 golem.Hp처럼 사용하기 때문에 private으로 선언된 hp 변수에는 전혀 접근하지 않습니다.

하지만 Hp라는 프로퍼티를 통해서 우회적으로 hp값을 return받을 수 있죠.

 

 

이러한 컨셉은 mp 변수에서도 마찬가지입니다.

 

 

using System;

class Monster
{
    private int hp = 100;
    private int mp = 100;

    public int Hp
    {
        set { hp = value; }
        get { return hp; }
    }

    public int Mp
    {
        set { mp = value; }
        get { return mp; }
    }
}

class MyProgram
{
    static void Main()
    {
        Monster golem = new Monster();

        golem.Hp = 1000;
        golem.Mp = 300;

        Console.WriteLine(golem.Hp);
        Console.WriteLine(golem.Mp);
    }
}


-- Result
1000
300

이제 원본 코드를 다시 봅시다.

 

Main method에서 Monster class를 불러와서 golem 객체를 만든 후

golem.Hp = 1000;

golem.Mp = 300;

위 코드 처럼 Hp, Mp 프로퍼티를 이용하여 hp, mp에 새로운 값을 할당하는 모습과

 

 

Console.WriteLine(golem.Hp);
Console.WriteLine(golem.Mp);

위처럼 golem 객체의 Hp, Mp 프로퍼티를 이용하여 우회적으로 hp, mp 값을 불러오는 모습이 이해되실겁니다.

 

 

 

 

 

 

728x90
반응형

'C# > C#' 카테고리의 다른 글

C# : WriteLine (문자 출력하기)  (0) 2022.03.23
C# : 상속 (Inheritance, sealed)과 다형성(Polymorphism)  (0) 2022.03.23
C# : 생성자(Constructor)  (0) 2022.03.23
C# : class와 object (class, 객체, Access Modifier)  (0) 2022.03.23
C# : method  (0) 2022.03.23
Comments