Class

protected
-protected 접근 지정자를 사용한 멤버 필드와 메소드는 파생 클래스에서는 사용가능하나 클래스 외부에서는 호출하지 못함


static
-static field는 전역 데이터로 클래스당 하나만 할당됨
-클래스명.정적필드명 형태로 사용
-static method는 class method나 static member field 조작을 위한 메소드
-static method는 instance field는 접근 불가능

constructor
-default constructor (기본 생성자)
-constructor overloading (생성자 오버로딩) 생성자를 여러 가지 형태로 정의
-constructor initializer (생성자 초기화 목록) 생성자들 사이의 정의가 비슷한 경우 코드를 간략하게 만들기 위해 사용

-private constructor (private 생성자) 정적 멤버만 포함하는 클래스에서 사용하며 클래스가 인스턴스화 될 수 없음을 분명히 하기 위해 private 접근 지정자를 사용
-static constructor (static 생성자)  정적 데이터 멤버를 초기화하는데 사용

destructor
-객체가 소멸될 때 필요한 정리 작업을 정의하는 부분

static constructor와 instance constructor 비교

C#은 두 가지 종류의 constructor, 즉 class constructor(static constructor), instance constructor(non-static constructor)를 지원한다.
 
static constructor
-static constructor는 static data member를 초기화하는데 사용
-static constructor는 접근 지정자를 쓸수 없음
-static constructor는 인자를 가질 수 없음
-static constructor는 non-static data member를 접근할 수 없음


// Test.cs
class Test
{
    //Declaration and initialization of static data member
    private static int id = 5;
    public static int Id
    {
        get
        {
            return id;
        }
    }

    public static void print()
    {
        Console.WriteLine(“Test.id=” + id);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Test.print(); // 정적 메소드를 사용하여 Test.id를 출력
    }

}


Test.id=5


 


// Test1.cs
class Test1
{
    private static int id;

    // static constructor를 사용하여 Test.id값에 따라서 Test1.id를 지정
    static Test()
    {
        if
( Test.Id < 10 )
        {
            id = 20;
        }
        else
        {
            id = 100;
        }
    }

    public static void print()
    {
        Console.WriteLine(“Test.id=” + id);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Test1.print(); // 정적 메소드를 사용하여 Test.id를 출력
    }
}


Test.id=20 // 정적 생성자 내에서 Test.id=5였기때문에 Test.id=20

instance constructor
-instance
constructor는 new 키워드를 사용하여 객체 생성에 사용
-instance constructor는 일반적으로  constructor라고 불림
constructor initializer는 생성자들 코드를 간략하게 만들기 위해 사용


public class MySimpleClass
{
    public MySimpleClass (int x)
    {
        Console.WriteLine (x);
    }
}
// 위의 코드는 컴파일러에서 아래의 코드처럼 해석
public
class MySimpleClass
{
    public MySimpleClass (int x) : base()
    {
        Console.WriteLine (x);
    }
}


public class MyClass
{
    private ArrayList col;
    private string name;
    public MyClass() : this(0,””) // 생성자 초기화목록을 사용하여 기본 생성자 지정
    {
    }
    public MyClass(int initialCount) : this (initialCount, “”)
    {
    }
    public MyClass(int initialCount, string name)
    {
        col = (initialCount > 0) ? new ArrayList(initialCount) : new ArrayList();
        this.name = name;
    }
}

-default constructor가 지정되어 있지 않다면 컴파일러에서 자동 생성해줌


public class MySimpleClass
{
    int someMemberVariable;
}
// 위의 코드를 컴파일러에서 아래와 같이 해석함
public class MySimpleClass
{
    int someMemberVariable;
               
    public MySimpleClass() : base()
    {
    }
}

-constructor는 상속되지 않음
public class MyBaseClass
{
    public MyBaseClass (int x)
    {
    }
}

public class MyDerivedClass : MyBaseClass
{
    // This constructor itself is okay – it invokes an
    // appropriate base class constructor
    public MyDerivedClass () : base (5)
    {
    }
             
    public static void Main()
    {
        new MyDerivedClass (10); // ERROR: MyDerivedClass는 인자를 받는 생성자가 없음
    }
}

singleton pattern과 static class 비교

공용 데이터를 저장하여 사용하고자 할 때, singleton 패턴이나 static 클래스를 사용한다.

1. 싱글톤 패턴 (Singleton design pattern)
-싱글톤 패턴이란 single instance object(해당 클래스의 인스턴스 하나)가 만들어지고, 어디서든지 그 싱글톤에 접근할 수 있도록 하기 위한 패턴


/// Sample singleton object.
public sealed class SiteStructure
{
    /// This is an expensive resource we need to only store in one place.
    object[] _data = new object[10];

    /// private constructor를 사용해서 static readonly로 객체 하나를 생성.
    static readonly SiteStructure _instance = new SiteStructure();

    /// 그 싱글톤에 접근하기 위한 property를 제공.
    public static SiteStructure Instance
    {
        get { return _instance; }
    }

    /// private constructor, 즉 외부에서는 이 생성자를 부를 수 없음.
    private SiteStructure()
    {
        // Initialize members, etc. here.
    }
}
// 싱글톤 객체를 인자로 전달 가능
SiteStructure site = SiteStructure.Instance;
OtherFunction(site); // Use singleton as parameter.



2. 정적 클래스 (Static class)
-static 키워드를 사용한 정적 클래스는 정적 멤버만 포함 가능
-정적 클래스는 new 키워드를 사용하여 정적 클래스의 인스턴스를 생성할 수 없음
-정적 클래스는 봉인 클래스 (sealed class) 임
-static 클래스는 single-instance, global 데이터를 저장하여 사용하는 용도로 적당
-그러나, 싱글톤은 인자(parameter)나 객체(object)로 사용가능하나 정적클래스는 불가능


/// Static class example.
static public class SiteStatic
{
    /// The data must be a static member in this example.
    static object[] _data = new object[10];

    /// C# doesn’t define when this constructor is run, but it will likely
    /// be run right before it is used.
    static SiteStatic()
    {
        // Initialize all of our static members.
    }
}


3. 싱글톤(Singleton)을 Interface와 함께 사용


/// Stores signatures of various important methods related to the site.
public interface ISiteInterface
{
};

/// ISiteInterface를 상속받은 SiteStructure 싱글톤
class SiteStructure : ISiteInterface
{
    // Implements all ISiteInterface methods.
    // 생략..
}

/// 테스트
class TestClass
{
    public TestClass()
    {
        // 싱글톤 객체를 ISiteInterface를 받는 함수에 인자로 전달.
        SiteStructure site = SiteStructure.Instance;
        CustomMethod((ISiteInterface)site);
    }

    /// Receives a singleton that adheres to the ISiteInterface interface.
    private void CustomMethod(ISiteInterface interfaceObject)
    {
        // Use the singleton by its interface.
    }
}



참고: http://dotnetperls.com/singleton-static

Assignment 2

연습문제 (2)


□ 단원 : C# 기초
□ 목표 : C# 프로그램 기초
□ 주요 연습 내용 : array, foreach, class, recursive call 사용 연습
□ 준비자료 : TicTacToe.cs1743820900.hwp


2263700716.cs
연습문제 Ex2 (Due by 10/12 화 24시까지)
-cyber 강의실 (cyber.dku.edu)로 source code, executable file, solution/project VC# file, 보고서를 학번_이름_Ex2.zip으로 묶어서 낼 것. 보고서 (30%)


[연습문제]
0. 3목 (Tic-Tac-Toe) 게임 프로그램을 작성하라. 3목 게임은 게임판의 지정된 행/열에 사람은 ‘X’ 수를 두고 컴퓨터는 ‘O’ 수를 번갈아 둔다. 행, 열, 대각선으로 3개의 ‘X’나 ‘O’가 존재하면 승자가 된다.


1. Board 클래스에는 보드를 표현하는 2차원 배열 matrix가 데이터 멤버로 포함되어야 한다. (50%)
– char[,] matrix;
– Board() 기본 생성자
– void InitBoard() 메소드는 matrix 보드에 값을 ‘ ‘으로 초기화
– bool IsFullBoard() 메소드는 matrix 보드에 빈값이 없으면 true를 반환
– bool IsEmpty(int i, int j) 메소드는 matrix 보드 (i,j) 위치에 빈값이 있으면 true 반환 – void Mark(int i, int j, char c) 메소드는 matrix 보드 (i,j) 위치에 ‘X’ 또는 ’O’를 표시
– void Unmark(int i, int j) 메소드는 matrix 보드 (i,j) 위치에 ‘ ‘로 표시
– char GetMarked(int i, int j) 메소드는 matrix 보드 (i,j) 위치에 있는 값을 반환
– char CheckThree() 메소드는 matrix 보드에 행, 열, 대각선으로 3개가 되는 것이 있는지 확인하고 어느 것인지를 반환. 만약 전체가 3개로 된 것이 없이 보드가 차면 ‘T’ 반환
– void DisplayBoard() 메소드는 matrix 보드를 화면에 표시
– void MoveByKeyboard(char c) 메소드는 화면에서 키보드 사용자의 입력을 받아서 원하는 matrix 보드 (i,j) 위치에 ‘X’ 또는 ’O’ 표시
– void MoveSimple(char c) 메소드는 matrix 보드에서 빈칸이 있으면 ‘X’ 또는 ’O’ 표시


2. Main 메소드에서는 게임 행동을 지정한다. (10%)
– 보드를 초기화한다.
– while 문을 사용하여 게임이 종료되기 전까지 ‘X’나 ‘O’ 수를 번갈아 두게 한다.
  이때 사람은 MoveByKeyboard(‘X’) 키보드 사용자 입력을 받아서 ‘X’ 수를 둔다.
  컴퓨터는 MoveSimple(‘O’) 보드의 빈칸 위치에 ‘O’ 수를 둔다.
– 만약 승자가 결정되었으면 누구인지 화면에 출력한다.
– 수를 둘 때마다 게임판을 화면에 출력한다.


3. Board 클래스에 MoveBest(int depth, char c) 메소드는 컴퓨터가 사람이 둔 수를 보고 Minimax 알고리즘 또는 Alpha Beta Pruning 알고리즘을 사용하여 최상의 조건에 ‘O’를 표시하는 이 메소드를 추가하라. 그리고 Main에서 MoveSimple 대신 MoveBest를 사용하여 테스트해본다. (10%)
http://en.wikipedia.org/wiki/Minimax
http://en.wikipedia.org/wiki/Alpha-beta_pruning


4. 프로그램에 본인이 더 테스트해보고 싶은 Method나 routine을 추가하라. (10%)

pass by value와 pass by reference와 pass by output 비교

pass value type by value (값형식을 값에 의한 전달)


static void Square1(int x)
{
     x *= x;
     Console.WriteLine(“The value inside the method: {0}”, x);
}
static void Main()
{
     int i = 5;
     Console.WriteLine(“i={0}”, i);
     Square1(i);
     Console.WriteLine(“i={0}”, i);
}

i=5
The value inside the method: 25
i=5

pass reference type by value (참조형식을 값에 의한 전달)
-copy of reference가 전달


static void ChangeArray1(int[] arr)
{
     arr[0]=888;       // 원본 배열의 첫번째 값은 888로 변경
     arr = new int[5] {-3, -1, -2, -3, -4}; // local 변수 재지정
     Console.WriteLine(“The value inside the method: arr[0]={0}”, arr[0]);
}
static void Main()
{
     int[] myArray = {1, 4, 5};
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
     ChangeArray1(myArray);
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
}

myArray[0]=1
The value inside the method: arr[0]=-3
myArray[0]=888


pass value type by reference (값형식을 참조에 의한 전달)
ref 키워드 사용


static void Square2(ref int x)
{
     x *= x;
     Console.WriteLine(“The value inside the method: {0}”, x);
}
static void Main()
{
     int i = 5;
     Console.WriteLine(“i={0}”, i);
     Square2(ref i);
     Console.WriteLine(“i={0}”, i);
}

i=5
The value inside the method: 25
i=25


pass reference type by reference (참조형식을 참조에 의한 전달)
ref 키워드 사용


static void ChangeArray2(ref int[] arr)
{
     arr[0]=888;       // 원본 배열의 첫번째 값은 888로 변경
     arr = new int[5] {-3, -1, -2, -3, -4}; // 원본 배열이 다시 변경
     Console.WriteLine(“The value inside the method: arr[0]={0}”, arr[0]);
}
static void Main()
{
     int[] myArray = {1, 4, 5};
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
     ChangeArray2(ref myArray);
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
}

myArray[0]=1
The value inside the method: arr[0]=-3
myArray[0]=-3


pass value type by output (값형식을 output에 의한 전달)
out 키워드 사용


static void Square3(int x, out int result)
{
     result = x*x;
     Console.WriteLine(“The value inside the method: {0}”, result);
}
static void Main()
{
     int i = 5;
     Console.WriteLine(“i={0}”, i);
     int result;
     Square3(i, out result);
     Console.WriteLine(“result={0}”, result);
}

i=5
The value inside the method: 25
result=25


pass reference type by output (참조형식을 output에 의한 전달)
out 키워드 사용


static void ChangeArray3(out int[] arr)
{
     //arr[0]=888;       // use of unassigned out parameter ‘arr’ ERROR
     arr = new int[5] {-3, -1, -2, -3, -4}; // 원본 배열이 변경
     Console.WriteLine(“The value inside the method: arr[0]={0}”, arr[0]);
}
static void Main()
{
     int[] myArray = {1, 4, 5};
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
     ChangeArray3(out myArray);
     Console.WriteLine(“myArray[0]={0}”, myArray[0]);
}

myArray[0]=1
The value inside the method: arr[0]=-3
myArray[0]=-3


참조: http://msdn.microsoft.com/en-us/library/0f66670z(VS.71).aspx

Just another Kyoung Shin Park’s Lectures Sites site