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 필드를 getter와 setter를 통해 간접적으로 제어할 수 있게 합니다.
- 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 키워드를 사용하여 정의되며, getter와 setter를 통해 값을 설정하고 반환합니다.
예시 코드:
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
매개변수를 받는 메소드를 참조하는 델리게이트. - 각각의 델리게이트를 통해
MethodA
와MethodB
를 호출할 수 있습니다.
결론:
델리게이트(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
구조체는X
와Y
좌표를 나타내며, 각각의 값이 독립적으로 복사됩니다.p1
과p2
는 서로 다른 값을 가지며, 하나의 값을 변경해도 다른 구조체에 영향을 미치지 않습니다.
10. 구조체와 클래스의 차이점
자료에서는 구조체와 클래스의 차이점도 설명하고 있습니다:
- 구조체는 값 형식이고, 클래스는 참조 형식입니다.
- 구조체는 스택에 저장되고, 클래스는 힙에 저장됩니다.
- 구조체는 상속을 지원하지 않으며, 생성자에서 필드를 초기화해야 합니다.
'2학년 2학기 > 윈도우즈 프로그래밍' 카테고리의 다른 글
인터페이스(2) - 인터페이스, 다중상속 (0) | 2024.09.30 |
---|---|
인터페이스(1) - 파생 클래스, 메소드 오버라이딩, 추상 클래스 (0) | 2024.09.30 |
클래스(1) - 클래스 선언, 생성, 필드, 메소드 (0) | 2024.09.30 |
필드와 프로퍼티의 차이 (0) | 2024.09.30 |
표준 입출력 (0) | 2024.09.30 |