C# 기초 정리 3 - 클래스와 객체

woollim·2024년 9월 22일
0

C#

목록 보기
3/11

1. 객체지향 프로그래밍

○ 객체지행 프로그래밍(Object-Oriented Programming, OOP)의 특징

  1. 캡슐화 (Encapsulation)
    • 관련된 데이터와 기능을 하나의 단위로 묶는 것을 의미
    • 클래스를 사용하여 데이터와 해당 데이터를 조작하는 메서드를 함께 캡슐화하여 정보를 은닉하고, 외부에서 직접적인 접근을 제한함으로써 안정성(보안성)과 유지보수성을 높임
  2. 상속 (Inheritance)
    • 상속은 기존의 클래스를 확장하여 새로운 클래스를 만드는 매커니즘
    • 부모 클래스의 특성과 동작을 자식 클래스가 상속 받아 재사용 할 수 있음
    • 코드의 중복을 줄이고, 클래스 간 계층 구조를 구성하여 코드의 구조화와 유지 보수를 용이하게 함
  3. 다형성 (Polymorphism)
    • 다형성은 하나의 인터페이스나 기능을 다양한 방식으로 구현하거나 사용할 수 있는 능력을 의미
    • 하나의 메서드 이름이 다양한 객체에서 다르게 동작할 수 있도록 하는 것으로, 오버로딩과 오버라이딩을 통해 구현
    • 유연하고 확장 가능한 코드 작성을 가능하게 하며, 코드의 가독성과 재사용성을 높임
  4. 추상화 (Abstraction)
    • 추상화는 복잡한 시스템이나 개념을 단순화하여 필요한 기능에 집중하는 것을 의미 함
    • 클래스나 인터페이스를 사용하여 실제 개념을 모델링하고, 필요한 부분에 대한 명세를 정의함
    • 세부 구현 내용을 감추고 핵심 개념에 집중함으로써 코드의 이해와 유지보수를 용이하게 함
  5. 객체 (Object)
    • 객체는 클래스로부터 생성된 실체로, 데이터와 해당 데이터를 조작하는 메서드를 가지고 있음
    • 객체는 상태(데이터)와 행동(메서드)을 가지며, 실제 세계의 개체나 개념을 모델링 함
    • 객체들 간의 상호작용을 통해 프로그램이 동작하고, 모듈화와 재사용성을 높임


2. 클래스와 객체

○ 클래스의 구성 요소

  1. 필드 (Fields)
    • 클래스에서 사용되는 변수. 객체의 상태를 나타내는 데이터를 저장하기 위해 사용
  2. 메서드 (Methods)
    • 클래스에서 수행되는 동작이 정의 됨. 객체의 동작을 구현하기 위해 사용 됨
  3. 생성자 (Constructors)
    • 객체를 초기화 하는 역할을 함. 객체가 생성될 때 자동으로 호출되며, 필드를 초기화 하는 등의 작업을 수행 함
  4. 소멸자 (Destructors)
class MyClass
{
    // 필드(데이터)
    private int myField;

    // 프로퍼티
    public int MyProperty { get; set; }

    // 생성자
    public MyClass(int fieldValue)
    {
        myField = fieldValue;
    }

    // 메서드(동작)
    public void DisplayValue()
    {
        Console.WriteLine("Value: " + myField);
    }
}

○ 클래스의 특성

  • 참조 타입 (Reference Type) : C#의 클래스는 참조 타입. 객체를 생성하면 힙 메모리에 할당되고, 변수는 그 객체의 참조(주소)를 가리킴. 따라서 클래스 인스턴스를 다른 변수에 할당하면 동일한 객체를 참조하게 됨.
MyClass obj1 = new MyClass(10);
MyClass obj2 = obj1;  // obj2와 obj1은 같은 객체를 참조
  • 상속 (Inheritance) : C#에서 클래스는 단일 상속을 지원함. 즉, 하나의 클래스만 상속받을 수 있음. 부모 클래스의 속성과 메서드를 자식 클래스에서 물려받아 사용할 수 있으며, 필요한 경우 재정의(Override)할 수 있음
class ParentClass
{
    public void ShowMessage()
    {
        Console.WriteLine("Parent class method");
    }
}

class ChildClass : ParentClass
{
    public void ShowChildMessage()
    {
        Console.WriteLine("Child class method");
    }
}
  • 다형성 (Polymorphism) : 클래스는 다형성을 통해 다양한 형태의 객체를 처리할 수 있음. virtual과 override 키워드를 사용해 가상 메서드를 정의하고, 파생 클래스에서 이를 재정의할 수 있음
class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Animal speaks");
    }
}

class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Dog barks");
    }
}
  • 캡슐화 (Encapsulation) : 클래스는 캡슐화를 통해 데이터(필드)를 보호하고, 외부에서는 제한된 방식으로만 접근할 수 있도록 함. 이를 통해 객체의 무결성을 유지할 수 있음. 주로 private 접근 지정자를 사용하여 필드를 보호하고, public 프로퍼티를 통해 안전하게 값을 제어 함

○ 클래스란?

  • 클래스는 객체를 생성하기 위한 템플릿 또는 설계도 역할을 함
  • 클래스는 속성과 동작을 가짐. 속성은 필드로, 동작은 메서드로 표현됨
  • 객체를 생성하기 위해서는 클래스를 사용하여 인스턴스를 만들어야 함

○ 객체란?

  • 객체는 클래스의 인스턴스. 클래스의 실체화된 형태라고 할 수 있음
  • 객체는 클래스로부터 생성되며, 각 객체는 독립적인 상태를 가지고 있음. 즉, 객체마다 고유한 데이터를 가질 수 있음

○ 클래스 선언과 인스턴스

  • 클래스(Class)는 데이터와 메서드를 하나로 묶은 사용자 정의 타입
class Person
{
    public string Name;
    public int Age;

    public void PrintInfo()
    {
        Console.WriteLine("Name: " + Name);
        Console.WriteLine("Age: " + Age);
    }
}

Person p = new Person();
p.Name = "John";
p.Age = 30;
p.PrintInfo();   // 출력: Name: John, Age: 30

○ 구조체와 클래스 차이점

  • 구조체와 클래스는 모두 사용자 정의 형식을 만드는 데 사용될 수 있음
  • 구조체는 값 형식이며, 스택에 할당되고 복사될 때 값이 복사 됨
  • 클래스는 참조 형식이며, 힙에 할당되고 참조로 전달되므로 성능 측면에서 다소 차이가 있음
  • 구조체는 상속 받을 수 없지만 클래스는 단일상속, 다중 상속이 가능 함
  • 구조체는 작은 크기의 데이터 저장이나 단순한 데이터 구조에 적합하며,
    클래스는 더 복잡한 객체를 표현하고 다양한 기능을 제공하기 위해 사용 됨


3. 접근 제한자

○ 접근 제한자 (Access Modifier)

  • 클래스, 필드, 메서드 등의 접근 가능한 범위를 지정하는 키워드.
    클래스의 캡슐화를 제어하는 역할
  • 종류
    • public : 외부에서 자유롭게 접근 가능
    • private : 같은 클래스 내부에서만 접근 가능
    • protected : 같은 클래스 내부와 상속받은 자식 클래스에서만 접근 가능
class Person
{
    public string Name;         // 외부에서 자유롭게 접근 가능
    private int Age;           // 같은 클래스 내부에서만 접근 가능
    protected string Address;  // 같은 클래스 내부와 상속받은 클래스에서만 접근 가능
}


4. 필드와 메서드

○ 필드 (Fields)

  • 필드는 클래스나 구조체 내에서 객체의 상태(데이터)를 저장하는 변수
  • 객체의 특징이나 속성을 표현하며, 클래스의 멤버 변수로 선언 됨
  • 보통 필드는 private 접근 제한자를 사용하여 외부에서 직접적인 접근을 제한하고,
    필요한 경우에는 프로퍼티를 통해 간접적으로 접근할 수 있도록 함
class Player
{
    // 필드 선언
    private string name;
    private int level;
}

○ 메서드 (Methods)

  • 메서드는 클래스나 구조체에서 객체의 동작(기능)을 정의하는 함수
  • 객체의 행동이나 동작을 구현하며, 클래스의 멤버 함수로 선언 됨
  • 메서드는 입력값을 받아서 처리하고, 결과값을 반환할 수도 있음
  • 객체의 상태를 변경하거나 다른 메서드를 호출하여 작업을 수행 함
  • 보통 메서드는 public 접근 제한자를 사용하여 외부에서 호출할 수 있도록 함
  • 메서드를 호출하기 위해서는 해당 메서드가 속해 있는 클래스의 인스턴스를 생성해야 함
    이후 생성된 인스턴스를 통해 메서드를 호출할 수 있음
class Player
{
    // 필드
    private string name;
    private int level;

    // 메서드
    public void Attack()
    {
        // 공격 동작 구현
    }
}
Player player = new Player();  // Player 클래스의 인스턴스 생성
player.Attack();  // Attack 메서드 호출


5. 생성자와 소멸자

○ 생성자

  1. 생성자란?
    • 생성자는 객체가 생성될 때 호출되는 특별한 메서드
    • 클래스의 인스턴스(객체)를 초기화하고, 필요한 초기값을 설정하는 역할을 수행 함
    • 생성자는 클래스와 동일한 이름을 가지며, 반환 타입이 없음
    • 객체를 생성할 때 new 키워드와 함께 호출 됨

  2. 생성자의 특징
    • 객체를 초기화하는 과정에서 필요한 작업을 수행할 수 있음
    • 생성자는 여러 개 정의할 수 있으며, 매개변수의 개수와 타입에 따라 다른 생성자를 호출할 수 있음. 이를 생성자 오버로딩이라고 함
    • 기본적으로 매개변수가 없는 디폴트 생성자가 클래스에 자동으로 생성되지만, 사용자가 직접 정의한 생성자가 있는 경우 디폴트 생성자가 자동으로 생성되지 않음
class Person
{
    private string name;
    private int age;

    // 매개변수가 없는 디폴트 생성자
    public Person()
    {
        name = "Unknown";
        age = 0;
    }

    // 매개변수를 받는 생성자
    public Person(string newName, int newAge)
    {
        name = newName;
        age = newAge;
    }

    public void PrintInfo()
    {
        Console.WriteLine($"Name: {name}, Age: {age}");
    }
}
Person person1 = new Person();                     // 디폴트 생성자 호출
Person person2 = new Person("John", 25);           // 매개변수를 받는 생성자 호출

○ 소멸자 (Destructor)

  1. 소멸자란?
    • 소멸자는 객체가 소멸되는 시점에서 자동으로 호출되는 특별한 메서드
    • 객체의 사용이 종료되고 메모리에서 해제될 때 자동으로 호출되어 필요한 정리 작업을 수행함
    • 클래스와 동일한 이름을 가지며, 이름 앞에 ~ 기호를 붙여 표현합니다.
    • 소멸자는 반환 타입이 없고 매개변수를 가질 수 없음
    • C#에서는 가비지 컬렉터(Garbage Collector)에 의해 관리되는 메모리 해제를 담당하므로, 명시적으로 소멸자를 호출하는 것은 일반적으로 권장되지 않음

  2. 소멸자의 역할
    • 자원 해제 : 파일 핸들, 네트워크 연결, 데이터베이스 연결 등의 외부 리소스를 사용한 경우, 소멸자를 통해 해당 리소스를 해제할 수 있음
    • 메모리 해제 : 객체가 사용한 메모리를 해제하고 관련된 자원을 정리할 수 있음
    • 로깅 및 디버깅 : 객체가 소멸되는 시점에 로깅 작업을 수행하거나 디버깅 정보를 기록할 수 있음
class Person
{
    private string name;

    public Person(string newName)
    {
        name = newName;
        Console.WriteLine("Person 객체 생성");
    }

    ~Person()
    {
        Console.WriteLine("Person 객체 소멸");
    }
}


6. 프로퍼티

○ 프로퍼티 (Property) 란?

  • 프로퍼티는 클래스 멤버로서, 객체의 필드 값을 읽거나 설정하는데 사용되는 접근자(Accessor) 메서드의 조합
  • 객체의 필드에 직접 접근하지 않고, 간접적으로 값을 설정하거나 읽을 수 있도록 함
  • 필드에 대한 접근 제어와 데이터 유효성 검사 등을 수행할 수 있음
  • 프로퍼티는 필드와 마찬가지로 객체의 상태를 나타내는 데이터 역할을 하지만, 외부에서 접근할 때 추가적인 로직을 수행할 수 있음

○ 프로퍼티 구문

  • 프로퍼티는 get과 set 접근자를 사용하여 값을 읽고 설정하는 동작을 정의
  • get 접근자는 프로퍼티의 값을 반환하고, set 접근자는 프로퍼티의 값을 설정
  • 필요에 따라 get 또는 set 접근자 중 하나를 생략하여 읽기 전용 또는 쓰기 전용 프로퍼티를 정의할 수 있음
[접근 제한자] [데이터 타입] 프로퍼티명
{
    get
    {
        // 필드를 반환하거나 다른 로직 수행
    }
    set
    {
        // 필드에 값을 설정하거나 다른 로직 수행
    }
}
  • 사용예시 : 다음은 Player 클래스의 이름과 레벨을 나타내는 name과 level 필드를 캡슐화한 프로퍼티
class Person
{
    private string name;
    private int age;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public int Age
    {
        get { return age; }
        set { age = value; }
    }
}
Person person = new Person();
person.Name = "John";   // Name 프로퍼티에 값 설정
person.Age = 25;        // Age 프로퍼티에 값 설정

Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");

○ 프로퍼티 접근 제한 적용 & 유효성 검사 예제

class Person
{
    private string name;
    private int age;

    public string Name
    {
        get { return name; }
        private set { name = value; }
    }

    public int Age
    {
        get { return age; }
        set
        {
            if (value >= 0)
                age = value;
        }
    }
}
Person person = new Person();
person.Name = "John";     // 컴파일 오류: Name 프로퍼티의 set 접근자는 private
person.Age = -10;         // 유효성 검사에 의해 나이 값이 설정되지 않음

○ 자동 프로퍼티 (Auto Property)

  • 자동 프로퍼티는 프로퍼티를 간단하게 정의하고 사용할 수 있는 편리한 기능
  • 필드의 선언과 접근자 메서드의 구현을 컴파일러가 자동으로 처리하여 개발자가 간단한 구문으로 프로퍼티를 정의할 수 있음
[접근 제한자] [데이터 타입] 프로퍼티명 { get; set; }
  • 사용 예시
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
Person person = new Person();
person.Name = "John";     // 값을 설정
person.Age = 25;          // 값을 설정

Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");  // 값을 읽어 출력


7. Static 클래스 및 멤버

  • C#에서는 정적(static) 클래스를 정의할 수 있음
  • 정적 클래스는 인스턴스를 생성하지 않고도 클래스의 메서드와 속성에 접근할 수 있음
  • 정적 멤버는 클래스 자체에 속하며, 모든 인스턴스에서 공유 됨
class Utility
{
    public static int Add(int a, int b)
    {
        return a + b;
    }
}
// 정적 메서드 호출
int result = Utility.Add(3, 4);


8. 부분 클래스 (Partial Class)

  • C#에서는 하나의 클래스를 여러 파일로 나눠서 정의할 수 있는 부분 클래스 기능을 지원 함
  • partial 키워드를 사용하여 클래스를 여러 파일에 나눠 정의하고, 컴파일 시 이들을 하나의 클래스로 합침
// File1.cs
partial class MyClass
{
    public void Method1() { }
}

// File2.cs
partial class MyClass
{
    public void Method2() { }
}


9. 인터페이스 구현

  • 클래스는 인터페이스를 구현할 수 있음.
  • 인터페이스는 클래스가 반드시 구현해야 하는 메서드와 속성의 청사진을 제공함
interface IMyInterface
{
    void MethodA();
}

class MyClass : IMyInterface
{
    public void MethodA()
    {
        Console.WriteLine("MethodA 구현");
    }
}


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

○ 값 타입 vs 참조 타입

  • 구조체 : 값 타입. 구조체 인스턴스가 복사될 때 값이 복사
  • 클래스 : 참조 타입. 클래스 인스턴스가 복사될 때 참조(주소)가 복사

○ 기본값

  • 구조체 : 기본 생성자가 제공되지 않으며, 생성 시 모든 필드는 기본값으로 초기화
  • 클래스 : 기본 생성자가 자동으로 제공되며, 인스턴스를 생성할 때 명시적으로 초기화할 수 있음

○ 상속

  • 구조체 : 다른 구조체나 클래스로부터 상속받을 수 없음
  • 클래스 : 상속이 가능. 다른 클래스에서 파생될 수 있음

○ 메모리 관리

  • 구조체 : 일반적으로 스택 메모리에 저장. 작은 데이터를 저장하는 데 적합
  • 클래스 : 힙 메모리에 저장되며, 가비지 컬렉터에 의해 관리. 더 복잡한 데이터 구조를 다루는 데 적합

○ 기본 동작

  • 구조체 : '==' 연산자를 오버로드하지 않으면 기본적으로 값 비교를 수행합니다.
  • 클래스 : '==' 연산자는 참조 비교를 수행. 값 비교를 원할 경우 Equals 메서드를 오버라이드해야 함

○ 요약

구조체는 가벼운 데이터 그룹을 다룰 때 적합하며, 클래스는 더 복잡한 데이터 및 동작을 다루는 데 적합합니다. 각기 다른 상황에 맞게 적절한 타입을 선택하는 것이 중요합니다.



11. 값 타입과 참조 타입

○ 값 타입 (Value Type)

  • 정의 : 값 타입은 실제 데이터가 변수에 저장.
    구조체와 기본 데이터 타입(예: int, float, bool 등)이 이에 해당
  • 메모리 할당 : 값 타입은 스택 메모리에 저장
  • 복사 : 값 타입의 변수를 다른 변수에 대입하면, 실제 값이 복사 됨. 두 변수는 서로 독립적임
int a = 5;
int b = a; // b는 5를 가지며, a와는 독립적
a = 10; // a의 값만 변경, b는 여전히 5

○ 참조 타입 (Reference Type)

  • 정의 : 참조 타입은 데이터가 메모리의 한 위치에 저장되고, 변수는 그 위치를 가리키는 참조(주소)를 저장
    클래스, 배열, 델리게이트 등이 이에 해당
  • 메모리 할당 : 참조 타입은 힙 메모리에 저장
  • 복사 : 참조 타입의 변수를 다른 변수에 대입하면, 참조가 복사. 두 변수는 동일한 객체를 가리킴
class MyClass
{
    public int Value;
}

MyClass obj1 = new MyClass();
obj1.Value = 5;

MyClass obj2 = obj1; // obj2는 obj1을 가리킴
obj1.Value = 10; // obj1의 값을 변경하면 obj2의 값도 변경됨

○ 요약

  • 값 타입 : 데이터가 변수에 직접 저장되고, 복사 시 실제 값이 복사
  • 참조 타입 : 데이터는 힙에 저장되고, 변수는 그 데이터의 주소를 참조함. 복사 시 참조가 복사됨


12. C++와 C#의 클래스 차이점

C++와 C#의 클래스는 기본적인 구조는 비슷하지만, 메모리 관리, 상속 방식, 다형성 구현 등에서 중요한 차이점이 있음. 아래에서 두 언어의 클래스 차이를 몇 가지 주요 항목을 중심으로 설명하겠음

○ 기본 접근 지정자

  • C++ : 클래스에서 접근 지정자를 명시하지 않으면 기본값은 private
  • C# : 클래스의 기본 접근 지정자는 internal이며, 클래스 멤버는 private
 // C++
class MyClass {
    int x;  // private
};
// C#
class MyClass {
    int x;  // private
}

○ 메모리 관리

  • C++ : 메모리 관리는 개발자가 직접 관리해야 하며, 동적 메모리는 new와 delete를 통해 수동으로 할당 및 해제
    • RAII(Resource Acquisition Is Initialization)를 통해 객체의 생명 주기를 관리할 수 있음
    • 가상 소멸자(virtual destructor)를 사용하여 상속된 클래스의 동적 메모리 관리가 안전하게 이루어지도록 해야 함
  • C# : 가비지 컬렉션(Garbage Collection)을 통해 메모리가 자동으로 관리 됨. new 키워드를 사용해 객체를 생성하면, 불필요해진 객체는 가비지 컬렉터가 자동으로 해제 함
    • 소멸자는 있지만, 가비지 컬렉터가 호출하는 시점은 개발자가 제어할 수 없음
    • IDisposable 인터페이스와 using 문을 사용해 명시적으로 리소스를 해제할 수 있음 참고 링크
// C++
class MyClass 
{
public:
    MyClass() { cout << "Constructor" << endl; }
    ~MyClass() { cout << "Destructor" << endl; }
};

int main() 
{
    MyClass* obj = new MyClass();  // 생성
    delete obj;  // 수동으로 해제
    return 0;
}
// C#
class MyClass 
{
    public MyClass() { Console.WriteLine("Constructor"); }
    ~MyClass() { Console.WriteLine("Destructor"); }
}

class Program 
{
    static void Main() 
    {
        MyClass obj = new MyClass();  // 가비지 컬렉터가 자동으로 해제
    }
}

○ 다중 상속

  • C++ : 다중 상속을 지원 함. 하나의 클래스가 여러 클래스로부터 상속받을 수 있음. 하지만 다중 상속은 복잡성을 증가시킬 수 있기 때문에 신중히 사용해야 함

  • C# : 다중 상속을 지원하지 않으며, 오직 단일 상속만 가능합니다. 하지만 인터페이스는 여러 개 구현할 수 있음

// C++ 다중 상속
class A { };
class B { };
class C : public A, public B { };  // 다중 상속 가능
// C# 단일 상속과 다중 인터페이스 구현
interface IA { }
interface IB { }

class C : IA, IB { }  // 다중 인터페이스 구현 가능

○ 다형성 (Polymorphism)

  • C++ : 다형성을 구현하려면 기본적으로 가상 함수(virtual functions)를 사용.
    파생 클래스에서 부모 클래스의 메서드를 재정의하려면, 부모 클래스 메서드에 virtual 키워드를 붙여야 하며, 파생 클래스에서는 override 키워드 없이도 재정의할 수 있음

  • C# : 다형성도 가상 메서드로 구현되지만, override 키워드를 반드시 사용해야 함.
    메서드를 가상 메서드로 만들기 위해 부모 클래스에서는 virtual, 파생 클래스에서는 override를 명시적으로 지정해야 함

// C++
class Base 
{
public:
    virtual void Speak() 
    {
        cout << "Base class" << endl;
    }
};

class Derived : public Base 
{
public:
    void Speak() override 
    {
        cout << "Derived class" << endl;
    }
};
// C#
class Base 
{
    public virtual void Speak() 
    {
        Console.WriteLine("Base class");
    }
}

class Derived : Base 
{
    public override void Speak() 
    {
        Console.WriteLine("Derived class");
    }
}

○ 인터페이스와 추상 클래스

  • C++ : C++에서는 추상 클래스를 통해 인터페이스를 흉내낼 수 있음. 순수 가상 함수(pure virtual function)를 사용하여 추상 클래스를 정의할 수 있으며, 이를 구현하는 클래스가 반드시 해당 함수를 재정의해야 함 순수 가상 함수 참고 링크
    • C++에는 인터페이스라는 명시적인 개념은 없음
  • C# : 인터페이스가 명확한 개념으로 존재하며, 추상 클래스와 구분 됨. 인터페이스는 멤버에 대한 구현을 포함하지 않으며, 클래스는 여러 인터페이스를 구현할 수 있음
// C++ 추상 클래스
class Shape
{
public:
    virtual void Draw() = 0;  // 순수 가상 함수
};
// C# 인터페이스
interface IShape
{
    void Draw();  // 구현 없음
}

○ 프로퍼티

  • C++ : C++에는 property라는 개념이 없으며, 직접 변수를 선언하거나 getter/setter 함수를 사용해야 함 참고링크

  • C# : 프로퍼티(property)를 통해 클래스 멤버 변수에 접근할 수 있으며, 이를 통해 데이터 접근을 캡슐화할 수 있습니다.

// C# 프로퍼티 예시
class MyClass 
{
    private int _value;
    
    public int Value 
    {
        get { return _value; }
        set { _value = value; }
    }
}

○ 이벤트와 델리게이트

  • C++ : 이벤트와 델리게이트를 직접 지원하지 않으며, 대신 함수 포인터나 객체 지향적인 방식으로 이벤트 시스템을 구현해야 함

  • C# : 델리게이트(delegate)이벤트(event)라는 특별한 구문을 지원하여, 이벤트 기반 프로그래밍을 쉽게 구현할 수 있음

// C# 델리게이트와 이벤트
public delegate void MyDelegate();

class MyClass {
    public event MyDelegate OnChange;
}

○ 차이 요약

  • 메모리 관리 : C++은 수동 관리(new/delete), C#은 자동 관리(가비지 컬렉터).
  • 상속 : C++은 다중 상속을 지원, C#은 단일 상속만 가능.
  • 다형성 : C++에서는 virtual과 override가 선택적이지만, C#에서는 필수.
  • 인터페이스 : C++에는 인터페이스 개념이 없고, C#에서는 명시적으로 제공됨.
  • 프로퍼티 : C#에는 프로퍼티가 있으며, C++에는 프로퍼티가 없음.
  • 이벤트 : C#은 델리게이트와 이벤트를 지원, C++은 직접 구현해야 함.

0개의 댓글