본문 바로가기

.NET/C#

Class(2)

728x90
반응형

클래스에 대해서 알아보는 두번째 시간입니다.

지난 시간에는 클래스의 기초적인 property의 사용법과 간단히 메소드 사용도 알아보았죠. 이번에는 클래스의 생성 및 객체 초기화에 대해서 알아보도록 하겠습니다.

클래스를 생성할 때 클래스와 똑같은 이름의 메소드를 본적이 있으실 겁니다. 그 메소드를 생성자메소드라고 합니다. 생성자메소드는 항상 클래스의 이름과 같고 결과형은 없습니다. 하지만 그게 void 형식이라는 것은 아닙니다. 왜인지 궁금하시다면 생성자메소드에 void를 살짝 붙여보시길 바랍니다 ^^;;

생성자 메소드는 객체 생성시(new 호출시) 자동으로 호출되며 명시적으로는 호출할 수 없습니다.

생성자 메소드 또한 overloading이 가능합니다. new호출의 전달인자 갯수와 종류로 생성자 메소드를 선택할 수 있는 거죠.

그리고 생성자 메소드를 정의하지 않으면 전달인자가 없는 생성자 메소드가 자동으로 제공되는 것입니다.
형태는 public classname() {} 이런식이지요

만약 명시적으로 생성자 메소드를 정의하면 전달인자 없는 생성자 메소드가 제공되지 않으므로 전달인자 있는 생성자 메소드를 정의할 경우 특별한 이유가 ㅇ벗는 한 전달인자 없는 생성자 메소드를 함께 정의하는 것이 좋습니다~.

생성자 메소드를 한번 구현 해볼까요~? (싫어도 해보세요!!은근 잼있음 ㅎㅎ)

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 

    6 namespace OOP2

    7 {

    8     class Product

    9     {

   10         public int Code { get; set; }

   11         public string Name { get; set; }

   12         public int Price { get; set; }

   13         public string GetProdcutInfo()

   14         {

   15             return string.Format("{0}. [{1}] [{2}]",Code,Name,Price);

   16         }

   17 

   18         public Product()

   19         {

   20             Console.WriteLine("전달인자 없는 생성자 메소드");

   21         }

   22 

   23         public Product(int code, string name, int price) : this()

   24         {

   25             Code = code;

   26             Name = name;

   27             Price = price;

   28             Console.WriteLine("전달인자 있는 생성자 메소드");

   29         }

   30     }

   31 }


이와같이  class를 실행하시고요 program의 메인 메소드에서는

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 

    6 namespace OOP2

    7 {

    8     class Program

    9     {

   10         static void Main(string[] args)

   11         {

   12             Product p = new Product();//생성자메서드호출시점 --> 생성자호출구문

   13             p.Code = 1;

   14             p.Name = "맛있는 사과음료";

   15             p.Price = 1500;

   16 

   17             Console.WriteLine(p.GetProdcutInfo());

   18         }

   19     }

   20 }


다음과 같이 구현 하시면 됩니다. 주석도 자세히 해났죠? ㅎㅎㅎ 뭐 그렇다고요 ㅋㅋ
Product 클래스에 보시면 생성자가 두개가 있는것이 보이죠 생성자메소드 overloading을 한것입니다.
전달인자 없는 것과 있는 것으로 나뉘죠. 위 코드에서는 전달인자 없이 호출하였으니 전달인자 없는 생성자메소드가 실행될것입니다. 결과는 다음과 같죠.

그럼 코드를 살짝 고쳐서 전달인자 있는 녀석으로 실행을 해보겠습니다.

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 

    6 namespace OOP2

    7 {

    8     class Program

    9     {

   10         static void Main(string[] args)

   11         {

   12             Product p = new Product(2, "재미있는 영화 DVD", 30000);

   13             Console.WriteLine(p.GetProdcutInfo());

   14         }

   15     }

   16 }

이렇게 실행을 하게 되면 좀 신기하게 나오는데요....

예상컨데 전달인자 있는 생성자 메소드만 출력 될꺼라 생각했지만 이게 왠일입니까? 없는 생성자 메소드도 같이 실행이 된거 있죠??제가 뭘 잘못 했나요??

네 그건 바로 Product 클래스에 있던 생성자 메소드중에 전달인자 있는 녀석에  : this() 요게 붙어 있는걸 볼수가 있지요

요건 클래스의 내부의 전달인자 없는 생성자 메소드를 호출 한다는 뜻으로 전달인자 있는 메소드 보다 먼저 호출되어 실행 되고 그 다음 있는 메소드가 실행되기 때문에 나타나는 현상입니다. 만약 저게 나오지 않게 하고 싶다면 : this()만 지워 주면 되겠지요 ^^

음...이것으로 마칠까하다가 하나만 더 하는게 날꺼 같아서 한가지 내용을 더 써볼려고 합니다~~
static형 멤버에 대해서 말씀 드려볼게요
static형 멤버는 객체별로 따로 생성되지 않고 오직 하나만 생성되어 모든 객체가 공유하는 멤버입니다. 그니깐 딱 하나만 존재 한다는 것이지요. static형 필드와 메서드 모두 만드는게 가능합니다.
static형 멤버는 객체의 참조를 통해서는 접근할 수 없고 오직 클래스 자체로만 접근이 가능합니다. 예를 들면 class이름.name 뭐...이런식으로요? ㅎㅎ
그리고 한가지더 말씀드리면...static은 객체 생성을 하지 않고 사용이 가능합니다!!
static형 메소드 영역에서는 instance형 멤버에 접근할 수 없다는게 또 다른 특징이겠지요 ^^
글엄~~간단히 테스트 코드로 확인을 해보도록 하겠습니다.

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 

    6 namespace OOP2

    7 {

    8     class Product2

    9     {

   10         private static int nextCode = 1;

   11         public static int NextCode

   12         {

   13             get

   14             {

   15                 return nextCode;

   16             }

   17         }

   18         private int code;

   19         public int Code

   20         {

   21             get { return code; }

   22         }

   23 

   24         public int Price { get; set; }

   25         public string Name { get; set; }

   26         public string GetProductInfo()

   27         {

   28             return string.Format("{0}. [{1}] [{2}]", Code, Name, Price);

   29         }

   30         public Product2()

   31         {

   32             code = nextCode;

   33             nextCode++;

   34         }

   35         public Product2(string name, int price)

   36             : this()

   37         {

   38             Name = name;

   39             Price = price;

   40         }

   41     }

   42 }

Product2라는 클래스를 하나 만들었습니다. 코드를 보시면 다 아시겠지만 static으로 정의된게 있지요 그 필드를 한번 메인에서 불러서 써보도록 하죠.

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 

    6 namespace OOP2

    7 {

    8     class Program

    9     {

   10         static void Main(string[] args)

   11         {

   12             Product2 pa = new Product2("카페모카", 5000);

   13             Product2 pb = new Product2("카푸치노", 4000);

   14             Product2 pc = new Product2("카페라떼", 4500);

   15 

   16             Console.WriteLine(pa.GetProductInfo());

   17             Console.WriteLine(pb.GetProductInfo());

   18             Console.WriteLine(pc.GetProductInfo());

   19 

   20             Console.WriteLine("NextCode : {0}", pa.NextCode); //static 형식은 참조로 읽지 못해 에러 발생

   21 

   22         }

   23     }

   24 }

컴파일시 에러가 발생해서 컴파일 자체도 일어나지 않습니다. static 형식은 저렇게 참조형으로는 사용할수가 없습니다.

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 

    6 namespace OOP2

    7 {

    8     class Program

    9     {

   10         static void Main(string[] args)

   11         {

   12             Product2 pa = new Product2("카페모카", 5000);

   13             Product2 pb = new Product2("카푸치노", 4000);

   14             Product2 pc = new Product2("카페라떼", 4500);

   15 

   16             Console.WriteLine(pa.GetProductInfo());

   17             Console.WriteLine(pb.GetProductInfo());

   18             Console.WriteLine(pc.GetProductInfo());

   19 

   20             //Console.WriteLine("NextCode : {0}", pa.NextCode); //static 형식은 참조로 읽지 못해 에러 발생

   21             Console.WriteLine("NextCode : {0}", Product2.NextCode);

   22         }

   23     }

   24 }

다음과 같이 하면 결과가 제대로 나오게 되지요.

보시는것과같이 결과는 4가 나오는것을 확인할 수 있습니다. 결국 static형의 멤버는 하나만을 가지고 씨나 씨++의 전역변수 같은 느낌을 준다고 생각할 수도 있습니다(저만의 생각입니다.)


많이 허접한 내용이지만 조금이나마 도움이 되었으면 하는 바램입니다~.

앞으로도 더 좋은 내용을 쓰기 위해 노력 하겠습니다~~

감사합니다~(__)

728x90
반응형

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

형변환에 대해서...  (0) 2009.12.18
System.Object 클래스 상속  (3) 2009.12.18
Property의 get, set 에 대한 간단한 정리  (0) 2009.12.18
Class(4)  (0) 2009.12.17
Class(3)  (0) 2009.12.17
Class(1)  (0) 2009.12.16
C# enum, struct  (0) 2009.12.16
C# Array 에 대해서...  (2) 2009.12.16
C# 메소드  (0) 2009.12.15
C# 반복문  (0) 2009.12.15