달나라 노트

C# : class와 object (class, 객체, Access Modifier) 본문

C#/C#

C# : class와 object (class, 객체, Access Modifier)

CosmosProject 2022. 3. 23. 15:48
728x90
반응형

 

 

 

C#은 객체지향 프로그래밍 언어입니다.

따라서 class를 선언해서 내가 원하는 정보들을 담아두고 원할 때 참조하여 사용할 수 있습니다.

 

 

 

using System;

public class my_test
{
    public string color = "White";
    public string size = "L";
}

class MyProgram
{
    static void Main()
    {
        my_test test_obj = new my_test();

        string color_info = test_obj.color;
        string size_info = test_obj.size;

        Console.WriteLine(color_info);
        Console.WriteLine(size_info);
    }
}

위 예시를 봅시다.

 

show_test라는 namespace 속을 보면 2개의 class가 선언되어있습니다.

 

하나는 my_test이며 다른 하나는 MyProgram입니다.

 

MyProgram class 안에는 Main method가 있네요. (Main method는 프로그램을 시작하면 실제로 실행되는 부분을 의미합니다.)

 

 

 

 

먼저 Main method에서 어떤 일이 일어나고있는지 봅시다.

 

...
    static void Main()
    {
        my_test test_obj = new my_test();

        string color_info = test_obj.color;
        string size_info = test_obj.size;

        Console.WriteLine(color_info);
        Console.WriteLine(size_info);
    }
...

불필요한 부분은 모두 생략하였습니다.

 

my_test test_obj = new my_test();

먼저 이 부분을 봅시다.

이 부분은 외부 class를 사용하기 위해 외부 class의 내용을 복사해서 test_obj라는 변수에 할당하는 부분입니다.

보면 int, double, float 등의 데이터를 할당하는게 아니라 이름이 my_test인 class를 할당하는 것이기 때문에 test_obj라는 변수명 왼쪽에 my_test라는 할당할 class 이름을 적어주었습니다. (class 자체가 자료형이 된다고 생각하면 좋습니다.)

 

그리고 등호(=)의 오른쪽에는 new라는 키워드가 있습니다. 새로운 class를 할당한다는 의미입니다.

new 키워드의 오른쪽에는 할당할 원본 class인 my_test() 가 적혀있습니다.

이렇게 새로운 class를 할당하여 객체를 생성할 때에는 new 키워드를 이용해야합니다.

 

결과적으로 test_obj 변수에는 my_test() class에 있는 모든 정보가 복사되어 할당됩니다.

 

 

 

 

 

 

 

...
public class my_test
{
    public string color = "White";
    public string size = "L";
}

class MyProgram
{
    static void Main()
    {
        my_test test_obj = new my_test();

        string color_info = test_obj.color;
        string size_info = test_obj.size;

        Console.WriteLine(color_info);
        Console.WriteLine(size_info);
    }
}
...

이제 좀 더 넓은 부분을 봐봅시다.

 

test_obj를 생성한 후 아래와 같은 부분이 있습니다.

 

string color_info = test_obj.color;
string size_info = test_obj.size;

 

이 구문의 의미는 test_obj에 있는 color 속성값을 color_info 변수에 할당하라는 의미입니다.

마찬가지로 test_obj에 있는 size 속성값을 size_info 변수에 할당하라는 의미이죠.

 

test_obj에 있는 color 속성값은 무엇을 의미할까요?

test_obj에 있는 size 속성값은 무엇을 의미할까요?

 

 

...
public class my_test
{
    public string color = "White";
    public string size = "L";
}
...

그건 바로 my_test class를 보면 알 수 있습니다.

 

my_test class의 정보를 그대로 복사해서 test_obj 변수에 넣었다고 했습니다.

 

my_test class는

White라는 String값을 담고있는 color라는 변수를 가지고 있었습니다.

또한 L이라는 String값을 담고있는 size라는 변수를 가지고 있었죠.

 

이러한 my_test class를 test_obj에 그대로 복사했기 때문에

test_obj도 White라는 String값을 담고있는 color라는 변수와 L이라는 String값을 담고있는 size라는 변수를 소유하게 됩니다.

이렇게 class 안에 있는 변수를 속성(attribute)이라고 합니다.

 

이렇게 속성값을 참조할 때에는 class_name.attribute_name 처럼 마침표(.)로 구분하면 됩니다.

 

참고로 class 안에 있는 변수들을 필드(field)라고도 합니다.

 

 

 

 

using System;

public class my_test
{
    public string color = "White";
    public string size = "L";
}

class MyProgram
{
    static void Main()
    {
        my_test test_obj = new my_test();

        string color_info = test_obj.color;
        string size_info = test_obj.size;

        Console.WriteLine(color_info);
        Console.WriteLine(size_info);
    }
}


-- Result
White
L

이 코드를 다시보면 결국 color, size 속성값을 받아와서 출력하는 코드입니다.

 

White와 L이 잘 출력된걸 볼 수 있죠.

 

 

 

 

이제 class에 method를 추가해봅시다.

 

method도 class안에 존재하는 정보 중 하나입니다.

속성(attribute)과 다른 점은 속성은 단순히 어떤 값을 가진 변수를 의미하지만

method는 어떤 기능을 가진 함수를 의미합니다.

 

아래 예시를 봅시다.

 

using System;

public class my_test
{
    public string color = "White";
    public string size = "L";

    public void show_info(string c, string s)
    {
        Console.WriteLine("Color = " + c);
        Console.WriteLine("Size = " + s);
    }
}

class MyProgram
{
    static void Main()
    {
        my_test test_obj = new my_test();

        string color_info = test_obj.color;
        string size_info = test_obj.size;

        Console.WriteLine(color_info);
        Console.WriteLine(size_info);
        test_obj.show_info(color_info, size_info);
    }
}


-- Result
White
L
Color = White
Size = L

코드를 약간 수정했는데 위 예시를 보면

 

 

public void show_info(string c, string s)

my_test class에 위같은 부분이 생겼습니다.

이 말은 my_test class에 show_info라는 이름의 기능을 가진 함수(= method)를 추가하겠다는 의미입니다.

 

그리고 이 함수의 내용을 보면 인자로 받은 c와 s값을 출력해줍니다.

 

 

 

 

 

...
    static void Main()
    {
        my_test test_obj = new my_test();

        string color_info = test_obj.color;
        string size_info = test_obj.size;

        Console.WriteLine(color_info);
        Console.WriteLine(size_info);
        test_obj.show_info(color_info, size_info);
    }
...

my_test에 show_info method를 선언해놨으니 그 정보를 그대로 복사한 test_obj도 show_info method를 보유하게 됩니다.

 

test_obj.show_info(color_info, size_info);

따라서 위처럼 test_obj에서 show_info method를 사용할 수 있죠.

 

 

이런식으로 class, method를 만들고 사용할 수 있습니다.

 

 

 

여기서 한 가지 중요한 내용이 있습니다.

 

using System;

public class my_test
{
    public string color = "White";
    public string size = "L";

    public void show_info(string c, string s)
    {
        Console.WriteLine("Color = " + c);
        Console.WriteLine("Size = " + s);
    }
}

class MyProgram
{
    static void Main()
    {
        my_test test_obj = new my_test();

        string color_info = test_obj.color;
        string size_info = test_obj.size;

        Console.WriteLine(color_info);
        Console.WriteLine(size_info);
        test_obj.show_info(color_info, size_info);
    }
}

위 코드를 다시 봅시다.

 

my_test class를 선언하는 부분을 보면 아래와 같이 변수를 선언하거나 method를 선언할 때 가장 왼쪽에 public이라는 키워드가 붙습니다.

 

왜일까요?

...
    public string color = "White";
    public string size = "L";

    public void show_info(string c, string s)
    {
        Console.WriteLine("Color = " + c);
        Console.WriteLine("Size = " + s);
    }
...

 

class를 선언하게 되면 자동적으로 보안 등급이 부여됩니다.

class 속에 있는 모든 속성과 모든 함수(method)에 보안 등급이 일일이 부여됩니다.

 

근데 public이라는 키워드를 적지 않으면 기본 보안 등급인 private 등급이 부여됩니다.

 

private 등급을 가진 속성이나 method는 test_obj같이 복사본을 받은 객체에서 사용할 수 없습니다.

 

 

...
public class my_test
{
    private string color = "White";
    private string size = "L";

    private void show_info(string c, string s)
    {
        Console.WriteLine("Color = " + c);
        Console.WriteLine("Size = " + s);
    }
}
...

따라서 위처럼 color, size 속성에 private 등급을 부여하게 되면 test_obj에서 color, size를 사용할 수 없습니다.

private으로 선언된 변수는 반드시 그 변수가 속한 class 안에서만 참조하여 사용할 수 있습니다.

 

method도 마찬가지로 show_info method를 private 등급으로 생성하면 test_obj에서 show_info method를 사용할 수 없습니다.

 

 

public, private 같은 보안 등급을 부여하는 키워드를 Access modifier라고 합니다.

 

Access Modifier와 관련된 설명은 아래 링크를 참조하면 자세히 나와있습니다.

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

 

 

 

 

 

Access Modifier는 왜 사용할까요?

 

using System;

class Monster
{
    public int hp = 100;
    public int mp = 100;
}

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를 생성하고 Main method에서 Monster class를 불러와 golem 객체를 생성했습니다.

그리고 golem의 hp, mp 정보를 입력해주었죠.

 

그 결과를 보면 제가 설정한대로 잘 표시되는것을 볼 수 있습니다.

 

근데 코딩을 하거나 프로그램을 실행할 때 golem.hp = -100; 과 같이 논리적으로 존재해서는 안되는 값을 할당하는 상황이 발생할 수 있습니다.

이런 경우 에러가 발생할 수 있죠.

 

이러한 상황을 방지하기 위해 보통 class에 있는 속성값들은 private으로 설정해두고 각 속성값에 접근할 수 있는 method를 만들어두는 것이 일반적입니다.

 

 

아래의 예시는 hp, mp를 private으로 설정해두고 Monster class 내부에서 hp, mp값을 설정하거나 얻어올 수 있는 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

 

 

 

 

Access Modifier 중 protected라는 것이 있습니다.

이것은 private과 동일한데 상속해준 class에는 접근을 가능하게 해줍니다.

 

원래 private으로 선언한 속성들은 상속시켜준 class에서도 접근할 수 없습니다.

하지만 protected로 속성을 선언해두면 상속해줬을 때 상속받은 자식 class에서는 protected로 선언된 변수들에 접근할 수 있습니다.

(하지만 class로 만들어진 객체에서는 여전히 접근 불가능합니다.)

 

 

 

 

 

 

 

 

 

 

using System;

public class my_test
{
    public string color = "White";
    public string size = "L";

    public void show_info(string c, string s)
    {
        Console.WriteLine("Color = " + c);
        Console.WriteLine("Size = " + s);
    }
}

class MyProgram
{
    static void Main()
    {
        my_test test_obj = new my_test();

        string color_info = test_obj.color;
        string size_info = test_obj.size;

        Console.WriteLine(color_info);
        Console.WriteLine(size_info);
        test_obj.show_info(color_info, size_info);
    }
}

자 이제 위 코드를 다시 봅시다.

 

한 가지 차이점이 있습니다. 바로 static 키워드에 관련된 것입니다.

 

my_test class에서 선언된 show_info method에는 static 키워드가 붙어있지 않습니다.

반변에 MyProgram class에서 선언된 Main method에는 static 키워드가 붙어있습니다.

 

무슨 차이일까요?

 

static 키워드가 붙은 method는 그 method가 속한 class 자체를 위한 것임을 의미합니다.

static 키워드가 없는 method는 그 method가 속한 class 자체를 위한 것이 아니라 다른 곳에서 class를 할당하여 사용할 함수의 용도라는 의미입니다.

 

 

my_test class를 선언하는 의도는 Main method나 다른 어떤 곳에서 my_test class의 기능을 복사해서 사용하기 위함입니다.

my_test class에 존재하는 속성인 color, size 그리고 method인 show_info 모두 코드의 다른 부분에서 어떠한 변수에 할당되어 사용할 속성과 기능입니다.

즉, my_test class에 있는 show_info method는 my_test라는 class 자체를 위해서 존재하는게 아니라 다른 어딘가에서 복사되어 사용될 method라는 것이죠. 이러한 method의 경우 static 키워드를 붙이지 않습니다.

 

반대로 MyProgram class의 Main method를 봅시다.

MyProgram class의 Main method는 프로그램을 실행시켰을 때 실질적으로 실행될 부분을 의미합니다.

Main method는 다른 어딘가에 복사해서 사용할 용도가 아닙니다.

따라서 Main method는 다른 무언가가 아니라 MyProgram class 자체만을 위한 method입니다.

이런 경우 "이 method는 속해있는 class 자체만을 위한 method에요."라는 의미로 static 키워드를 붙이게 됩니다.

 

 

이와 비슷한 내용이 아래 링크에도 적혀있습니다.

https://cosmosproject.tistory.com/198?category=972064

 

Java - object (객체)

class의 개념에 대해 이해해봅시다. 객체 지향적, 객체, class 등은 단순히 어떤 프로그램의 로직을 나열하는 것이 아닌 사람이 사물을 보는 시각처럼 프로그램을 구성하는 것입니다.

cosmosproject.tistory.com

 

Java가 C#과 매우 비슷하기에 개념도 비슷합니다.

class의 선언과 static, public, private 키워드 등의 쓰임새도 매우 비슷하니 위 설명도 읽어보면 이해해 도움이 될겁니다.

 

 

 

 

 

 

728x90
반응형
Comments