객체지향 프로그래밍
  • 캡슐화 - 관련된 데이터와 기능을 하나의 단위로 묶는 것. 정보를 은닉하고 외부에서 직접적인 접근을 제한하여 안정성과 유지보수성을 높힌다.
  • 상속 - 부모 클래스의 특성과 동작을 자식 클래스가 상속받아 재사용한다. 코드의 중복을 줄이고 코드의 구조화와 유지보수를 용이하게 한다.
  • 다형성 - 오버로딩, 오버라이딩을 통해 하나의 메서드 이름으로 다양한 동작을 할 수 있다. 코드의 가독성과 재사용성을 높힌다.
  • 추상화 - 복잡한 기능을 단순화하여 필요한 기능에 집중한다.(세부 구현을 감추고 개념을 구현)
  • 객체 - 데이터와 메서드를 가지고 있으면서 실제로 상호작용하며 프로그램이 동작하는 것. 클래스로 구현되어 모듈화나 재사용성이 높다.

 

 

클래스

객체를 생성하기 위한 템플릿 또는 설계도. 데이터와 메서드를 하나로 묶은 사용자 정의 타입. 속성이나 동작에 대한 정의가 되어 있다. 클래스를 통해 인스턴스(객체)를 만들 수 있다.

- 구성요소: 필드(맴버변수), 메서드(맴버함수), 생성자(객체가 형성될 때 자동으로 호출되는 메서드), 소멸자(메모리에서 소멸될 때 자동으로 생성되는 메서드)

 

객체

클래스로 생성된 인스턴스. 클래스의 실체화된 형태. 독립적인 상태로 고유의 데이터를 가지고 있다.

 

// 클래스 선언
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

 

구조체와 클래스

  • 구조체와 클래스 모두 사용자 정의 형식. 우리가 원하는 자료형과 기능들을 뭉쳐 놓은 상태이다.
  • 구조체는 값 형식이며, 스택이라는 메모리에 각자 자동으로 할당된다.
  • 클래스는 참조 형식이며, 힙 영역에 동적 할당된다.
  • 구조체는 상속을 받을 수 없지만 클래스는 단일 상속과 다중상속이 가능하다.
  • 구조체는 작은 크기의 데이터나 단순한 구조를 작성할 때 적합하고 복잡한 경우에 클래스가 훨씬 더 사용하기 편하다.

 

접근 제한자

  • public: 외부에서 자유롭게 접근 가능
  • private: 같은 클래스 내부의 메서드나 필드에서 접근 가능
  • protected: 같은 클래스 내부와 상속 받은 자식까지만 접근 가능

 

필드

클래스 내부에 선언된 변수(맴버 변수). 데이터를 저장한다.

객체의 특징이나 속성들을 표현하기 위해 사용하며, 일반적으로 외부에서 접근하지 못하도록  private로 접근 제한자를 사용한다.

class Player
{
    // 필드 선언
    private string name;
    private int level;
}

 

메서드

클래스 내부에 선언된 함수(맴버 함수). 클래스의 동작을 정의한다.

클래스나 구조체에 대한 기능들을 정리하며, 일반적으로 외부에서 호출할 수 있도록 public으로 만들어준다.

class Player
{
    // 필드
    private string name;
    private int level;

    // 메서드
    public void Attack()
    {
        // 공격 동작 구현
    }
}

Player player = new Player();  // Player 클래스의 인스턴스 생성
player.Attack();  // Attack 메서드 호출

 

생성자

객체를 생성할 때 호출되는 메서드. 객체를 초기화하고 필요한 초기값을 설정하는 역할을 한다.

  • 클래스와 동일한 이름을 가지고 있으며, 반환 타입이 없다.
  • 여러 개를 정의 할 수 있고 매개변수의 개수와 타입에 따라 다른 생성자를 호출 할 수 있다.(오버로딩)
  • 기본적으로 매개변수가 없는 디폴트 생성자가 자동으로 생성되지만, 최소 하나라도 생성자를 만들었다면 디폴트 생성자는 더 이상 만들어지지 않는다.
class Person
{
    private string name;
    private int age;

    public void PrintInfo()
    {
        Console.WriteLine($"Name: {name}, Age: {age}");
    }
}



Person person1 = new Person();

 

소멸자

객체가 소멸이 될 때 호출되는 메서드.

  • 클래스와 동일한 이름을 가지고 있으며, 이름 앞에 ~ 기호를 붙인다.
  • 가비지 컬렉터(Garbage Collector)가 클래스가 아무데도 사용되지 않아서 메모리를 해제할 때 소멸자가 자동으로 호출된다.
  • 파일 핸들, 네트워트 연결, 데이터베이스 연결 등 외부적인 파일들에 대한 자원을 해제할 수 있다.
  • 배열이나 다른 클래스들의 선언을 인위적으로 해제할 수 있다.
  • 소멸이 언제 되는지에 대한 로깅과 디버깅을 할 수 있다.
  • 오버로딩 할 수 없다.
class Person
{
    private string name;

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

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

 

프로퍼티(Property)

은닉화한 필드값(private 등)을 외부에서도 접근할 수 있는 중간 매개 역할을 만들어주는 것.

프로퍼티를 사용하여 데이터 유효성이나 제한을 거는 등 필드 접근을 제한하면 코드의 안정성과 가독성을 높힐 수 있다.

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}");  // Name과 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;         // 유효성 검사에 의해 나이 값이 설정되지 않습니다.

Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");  // Name과 Age 프로퍼티에 접근하여 값을 출력합니다.

 

자동 프로퍼티

프로퍼티를 간단히 정의하고 사용할 수 있도록 한다. 필드의 선언과 접근자 메서드의 구현을 컴파일러가 자동으로 처리한다.

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}");  // 값을 읽어 출력

 

 

+ Recent posts