본문 바로가기
2학년 2학기/윈도우즈 프로그래밍

클래스(2) - 메소드 / 연산자 오버로딩, 생성자, 인덱서, 프로퍼티

by kkkkk1023 2024. 9. 30.

1. 메소드 중복 (Method Overloading)

 

  • 메소드 시그니처(Signature): 메소드를 구분하는 정보로 메소드 이름, 매개변수 개수, 매개변수 자료형을 포함합니다. 반환형은 시그니처에 포함되지 않습니다.
  • 메소드 중복: 같은 이름의 메소드를 여러 개 정의할 수 있으며, 매개변수의 개수나 자료형이 다르면 다른 메소드로 취급됩니다. 이를 통해 같은 이름의 메소드를 다양하게 활용할 수 있습니다.

 

예시 코드:

class MethodOverloadingApp {
    void SomeThing() {
        Console.WriteLine("SomeThing() is called.");
    }

    void SomeThing(int i) {
        Console.WriteLine("SomeThing(int) is called.");
    }

    void SomeThing(int i, int j) {
        Console.WriteLine("SomeThing(int, int) is called.");
    }

    void SomeThing(double d) {
        Console.WriteLine("SomeThing(double) is called.");
    }

    public static void Main() {
        MethodOverloadingApp obj = new MethodOverloadingApp();
        obj.SomeThing();         // No parameters
        obj.SomeThing(526);      // One integer parameter
        obj.SomeThing(54, 526);  // Two integer parameters
        obj.SomeThing(5.26);     // One double parameter
    }
}

 

 

실행 결과:

SomeThing() is called.
SomeThing(int) is called.
SomeThing(int, int) is called.
SomeThing(double) is called.

 

 

2. 생성자 (Constructor)

  • 생성자는 객체가 생성될 때 자동으로 호출되는 메소드입니다. 클래스의 이름과 같으며, 반환형을 가지지 않습니다.
  • 생성자는 주로 객체를 초기화하는 데 사용됩니다.
  • 생성자 중복도 가능하며, 매개변수에 따라 다른 생성자가 호출됩니다.

예시 코드:

class Fraction {
    private int numerator;
    private int denominator;

    public Fraction(int a, int b) {  // 생성자
        numerator = a;
        denominator = b;
    }

    public override string ToString() {
        return numerator + "/" + denominator;
    }
}

class Program {
    public static void Main() {
        Fraction f = new Fraction(1, 2);  // 1/2
        Console.WriteLine(f.ToString());
    }
}

 

 

 

실행 결과:

1/2

 

 

3. 정적 생성자 (Static Constructor)

  • 정적 생성자static으로 선언되며, 매개변수접근 수정자를 가질 수 없습니다. 이는 클래스의 정적 필드를 초기화하는 데 사용되며, Main 메소드보다 먼저 실행됩니다.

예시 코드:

class StaticConstructor {
    static int staticWithInitializer = 100;
    static int staticWithNoInitializer;

    static StaticConstructor() {
        staticWithNoInitializer = staticWithInitializer + 100;
    }

    public static void PrintStaticVariable() {
        Console.WriteLine($"Field 1 = {staticWithInitializer}, Field 2 = {staticWithNoInitializer}");
    }
}

class Program {
    public static void Main() {
        StaticConstructor.PrintStaticVariable();
    }
}

실행 결과:

Field 1 = 100, Field 2 = 200

 

 

 

4. 프로퍼티 (Property)

  • 프로퍼티는 클래스의 private 필드를 gettersetter를 통해 간접적으로 제어할 수 있게 합니다.
  • get 접근자는 값을 반환하고, set 접근자는 값을 설정합니다. 프로퍼티는 필드처럼 사용되지만 메소드처럼 동작하여, 필드에 대한 제어된 접근을 제공합니다.

예시 코드:

class Fraction {
    private int numerator;
    private int denominator;

    public int Numerator {
        get { return numerator; }
        set { numerator = value; }
    }

    public int Denominator {
        get { return denominator; }
        set { denominator = value; }
    }

    public override string ToString() {
        return numerator + "/" + denominator;
    }
}

class Program {
    public static void Main() {
        Fraction f = new Fraction();
        f.Numerator = 1;           // set
        f.Denominator = 2;         // set
        Console.WriteLine(f.ToString());  // get
    }
}

실행 결과:

1/2

 

 

 

5. 인덱서 (Indexer)

  • 인덱서는 배열처럼 객체의 인덱스를 사용하여 값을 설정하거나 가져올 수 있게 해줍니다. this 키워드를 사용하여 정의되며, gettersetter를 통해 값을 설정하고 반환합니다.

예시 코드:

class Color {
    private string[] colors = new string[5];

    public string this[int index] {
        get { return colors[index]; }
        set { colors[index] = value; }
    }
}

class Program {
    public static void Main() {
        Color color = new Color();
        color[0] = "Red";
        color[1] = "Blue";
        color[2] = "Green";
        color[3] = "Yellow";
        color[4] = "Black";

        for (int i = 0; i < 5; i++) {
            Console.WriteLine(color[i]);
        }
    }
}

실행 결과:

Red
Blue
Green
Yellow
Black

 

 

 

6. 연산자 중복 (Operator Overloading)

  • 연산자 중복은 C#에서 제공하는 기본 연산자를 클래스의 객체에 맞게 재정의할 수 있게 해줍니다.
  • 연산자는 반드시 public static으로 정의해야 하며, 연산자가 계산된 결과에 맞는 반환형을 가져야 합니다.

형태

public static 반환형 operator 연산자(매개변수 목록) {
    // 연산자 중복 구현
}

 

 

예시 코드:

class Complex {
    private double real;
    private double imaginary;

    public Complex(double real, double imaginary) {
        this.real = real;
        this.imaginary = imaginary;
    }

    public static Complex operator +(Complex a, Complex b) {
        return new Complex(a.real + b.real, a.imaginary + b.imaginary);
    }

    public override string ToString() {
        return $"{real} + {imaginary}i";
    }
}

class Program {
    public static void Main() {
        Complex c1 = new Complex(1, 2);
        Complex c2 = new Complex(3, 4);
        Complex c3 = c1 + c2;
        Console.WriteLine($"{c1} + {c2} = {c3}");
    }
}

실행 결과:

(1 + 2i) + (3 + 4i) = (4 + 6i)

 

 

 

7. 델리게이트(Delegate)

 

델리게이트는 C#에서 메소드를 참조하기 위한 형식 안전한 방법입니다. 메소드를 변수처럼 저장하고 호출할 수 있으며, 이는 특히 이벤트 처리에 자주 사용됩니다. 델리게이트는 정적 메소드 또는 인스턴스 메소드를 참조할 수 있으며, 델리게이트와 참조하는 메소드의 시그니처가 일치해야 합니다.

델리게이트 선언과 사용:

자료에서 제공된 델리게이트 선언과 사용 예시는 다음과 같습니다.

using System;
delegate void DelegateOne(); // 매개변수가 없는 델리게이트
delegate void DelegateTwo(int i); // 하나의 매개변수가 있는 델리게이트

class DelegateClass {
    public void MethodA() {
        Console.WriteLine("In the DelegateClass.MethodA ...");
    }

    public void MethodB(int i) {
        Console.WriteLine($"DelegateClass.MethodB, i = {i}");
    }
}

class DelegateCallApp {
    public static void Main() {
        DelegateClass obj = new DelegateClass();

        // 델리게이트 객체 생성
        DelegateOne d1 = new DelegateOne(obj.MethodA); 
        DelegateTwo d2 = new DelegateTwo(obj.MethodB); 

        d1(); // MethodA 호출
        d2(10); // MethodB 호출
    }
}

실행 결과:

In the DelegateClass.MethodA ...
DelegateClass.MethodB, i = 10

설명:

  • DelegateOne: 매개변수가 없는 메소드를 참조하는 델리게이트.
  • DelegateTwo: int 매개변수를 받는 메소드를 참조하는 델리게이트.
  • 각각의 델리게이트를 통해 MethodAMethodB를 호출할 수 있습니다.

결론:

    델리게이트(Delegate)를 활용하면 직접 메소드에 접근할 필요 없이, 델리게이트 객체를 통해 메소드를 호출할 수 있습니다. 델리게이트는 메소드 참조를 저장하는 일종의 형식 안전한 포인터로, 메소드 이름을 직접 사용하지 않고도 델리게이트 객체를 통해 해당 메소드를 동적으로 호출할 수 있습니다.

 

 

8. 이벤트(Event)

 

이벤트델리게이트를 기반으로 한 구조로, 특정 사건이 발생했을 때 이를 처리하는 메커니즘입니다. 예를 들어, 버튼이 클릭되었을 때 이를 처리하는 메소드를 연결하여 사용합니다. C#에서는 event 키워드를 사용해 이벤트를 정의하고, 델리게이트와 연결하여 처리합니다.

자료의 이벤트 예시 코드:

using System;

public delegate void MyEventHandler();  // 이벤트를 위한 델리게이트 선언

class Button {
    public event MyEventHandler Push;  // 이벤트 선언

    public void OnPush() {
        if (Push != null)
            Push();  // 이벤트 발생
    }
}

class EventHandlerClass {
    public void MyMethod() {
        Console.WriteLine("In the EventHandlerClass.MyMethod ...");
    }
}

class EventHandlingApp {
    public static void Main() {
        Button button = new Button();
        EventHandlerClass obj = new EventHandlerClass();

        // 이벤트 처리기 등록
        button.Push += new MyEventHandler(obj.MyMethod); 

        button.OnPush();  // 클릭 이벤트 발생
    }
}

실행 결과:

In the EventHandlerClass.MyMethod ...

설명:

  • 이벤트는 버튼이 클릭되었을 때 Push 이벤트가 발생하고, MyMethod가 호출됩니다.
  • 이벤트는 델리게이트를 통해 메소드를 연결하고, 사건 발생 시 해당 메소드가 호출됩니다.

 

 

 

9. 구조체(Struct)

 

구조체(Struct)클래스와 비슷하지만 값 형식(value type)입니다. 구조체는 주로 간단한 데이터 구조를 정의하는 데 사용됩니다. 클래스는 참조 형식(reference type)인 반면, 구조체는 값 자체를 복사하여 전달합니다.

자료의 구조체 예시 코드:

using System;

struct Point {
    public int X;  // 필드
    public int Y;  // 필드

    public Point(int x, int y) {  // 생성자
        X = x;
        Y = y;
    }

    public void Print() {  // 메소드
        Console.WriteLine($"Point: ({X}, {Y})");
    }
}

class StructApp {
    public static void Main() {
        Point p1 = new Point(10, 20);  // 구조체 인스턴스 생성
        p1.Print();

        Point p2 = p1;  // 값 복사
        p2.X = 30;

        p1.Print();  // p1 값은 변하지 않음
        p2.Print();  // p2의 값만 변경됨
    }
}

실행 결과:

Point: (10, 20)
Point: (10, 20)
Point: (30, 20)

설명:

  • Point 구조체는 XY 좌표를 나타내며, 각각의 값이 독립적으로 복사됩니다.
  • p1p2는 서로 다른 값을 가지며, 하나의 값을 변경해도 다른 구조체에 영향을 미치지 않습니다.

 

 

10. 구조체와 클래스의 차이점

자료에서는 구조체와 클래스의 차이점도 설명하고 있습니다:

  • 구조체값 형식이고, 클래스참조 형식입니다.
  • 구조체스택에 저장되고, 클래스에 저장됩니다.
  • 구조체는 상속을 지원하지 않으며, 생성자에서 필드를 초기화해야 합니다.