
캡슐화는 데이터(속성)와 그 데이터를 처리하는 메서드를 하나의 클래스 단위로 결합하는 것을 의미한다.
데이터의 세부 구현을 숨기고, 클래스의 공개 인터페이스만을 통해 데이터에 접근할 수 있게 함으로써 프로그램의 안정성과 유지 보수성을 향상시킨다.
상속은 한 클래스(부모 클래스, 상위 클래스)가 자신의 속성과 메서드를 다른 클래스(자식 클래스, 하위 클래스)에게 전달하는 메커니즘이다.
코드의 중복을 줄이고, 클래스 간 계층 구조를 구성하여 코드의 구조화와 유지보수를 용이하게 한다.
다형성은 동일한 인터페이스 또는 메서드 호출이 다양한 형태의 객체에 대해 다른 동작을 할 수 있게 하는 프로그래밍 기능이다.
메서드 오버로딩(동일한 메서드 이름이지만 서로 다른 매개변수를 가짐)과 메서드 오버라이딩(파생 클래스에서 베이스 클래스의 메서드를 재정의)을 통해 구현된다.
추상화는 복잡한 시스템이나 개념을 단순화하여 필요한 기능에 집중하는 것을 의미한다.
클래스와 인터페이스를 통해 구현되며, 주로 필요한 속성과 동작만을 갖는 형태로 실제 세계의 개체를 모델링하여, 프로그램 내에서 필수적인 부분에만 집중할 수 있게 한다.
객체는 클래스로부터 생성된 실체로, 클래스에 정의된 속성(데이터)과 동작(메서드)을 가진다.
각 객체는 독립적인 상태와 행동을 가지고 있으며, 다른 객체와 상호 작용하면서 프로그램의 기능을 수행한다.
클래스의 멤버 변수로 선언되며, 객체의 특징이나 속성을 표현하고 객체의 데이터를 저장한다.
보통 private 접근 제한자를 사용하여 클래스 외부에서 직접적인 접근을 제한하고, 필요한 경우 프로퍼티를 통해 간접적으로 접근하도록 한다.
class Player
{
// 필드
private string name;
private int level;
}
class Person
{
public string Name; // 외부에서 자유롭게 접근 가능
private int Age; // 같은 클래스 내부에서만 접근 가능
protected string Address; // 같은 클래스 내부와 상속받은 클래스에서만 접근 가능
}
프로퍼티는 클래스 멤버로서, 객체의 필드 값을 간접적으로 읽거나 설정할 수 있게 하는 접근자 메서드의 조합으로, 필드에 대한 접근 제어 및 데이터 유효성 검사를 수행하면서 추가 로직을 통한 상태 관리를 가능하게 한다.
get과 set 접근자를 사용하여 값을 읽거나 설정하는 동작을 정의한다.
get 접근자는 프로퍼티의 값을 반환하고, set 접근자는 프로퍼티의 값을 설정한다.
필요에 따라 get 또는 set 접근자 중 하나를 생략하여 읽기 전용 또는 쓰기 전용 프로퍼티를 정의할 수 있다.
[접근 제한자] [데이터 타입] 프로퍼티명
{
get
{
// 필드를 반환하거나 다른 로직 수행
}
set
{
// 필드에 값을 설정하거나 다른 로직 수행
}
}
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";
person.Age = 25;
Console.WriteLine($"Name: {person.Name}, Age: {person.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; // 유효성 검사에 의해 나이 값이 설정되지 않는다.
[접근 제한자] [데이터 타입] 프로퍼티명 { get; set; }
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
클래스의 멤버 함수로 선언되며, 객체의 기능이나 동작을 구현하기 위해 사용되며, 입력값을 받아서 처리한 후 결괏값을 반환, 다른 메서드를 호출하여 작업, 객체의 상태 변경 등을 수행한다.
보통 public 접근 제한자를 사용하여 클래스 외부에서 호출할 수 있도록 한다.
class Player
{
private string name;
private int level;
// 메서드
public void Attack()
{
// 공격 동작 구현
}
}
// Player 클래스의 인스턴스 생성
Player player = new Player();
// Attack 메서드 호출
player.Attack();
객체가 생성될 때 호출되는 특별한 메서드로서 클래스의 인스턴스(객체)를 초기화하고, 필요한 초깃값을을 설정하는 역할을 수행한다.
객체를 생성할 때 new 키워드와 함께 호출되고, 클래스와 동일한 이름을 가지며, 반환 타입이 없다.
매개변수의 유무나 타입, 개수에 따라 다르게 객체를 초기화할 수 있는 생성자를 여러 개 정의할 수 있으며, 이를 생성자 오버로딩(Overloading)이라고 한다.
기본적으로 매개변수가 없는 디폴트 생성자가 자동으로 클래스에 생성되지만, 직접 생성자를 정의할 경우 디폴트 생성자가 자동으로 생성되지 않는다.
class Player
{
private string name;
private int level;
// 매개변수가 없는 디폴트 생성자
public Player()
{
name = "Unknown";
level = 0;
}
// 매개변수를 받는 생성자
public Player(string newName, int newLevel)
{
name = newName;
level = newLevel;
}
public void PrintInfo()
{
Console.WriteLine($"Name: {name}, Level: {level}");
}
}
// 디폴트 생성자 호출
Player player1 = new Player();
// 매개변수를 받는 생성자 호출
Player player2 = new Player("John", 25);
객체가 소멸되는 시점에서 자동으로 호출되는 특별한 메서드로서 객체의 사용이 종료되고 메모리에서 해제될 때 자동으로 호출되어 필요한 정리 작업을 수행한다.
이름 앞에 ~ 기호를 붙여 표현하고, 클래스와 동일한 이름을 가지며, 반환 타입이 없고, 매개변수를 가질 수 없다.
C#에서는 가비지 컬렉터(Garbage Collector)가 메모리 해제를 관리하므로, 소멸자를 명시적으로 호출하는 것은 일반적으로 권장되지 않는다.
class Player
{
private string name;
public Player(string newName)
{
name = newName;
Console.WriteLine("Player 객체 생성");
}
~Player()
{
Console.WriteLine("Player 객체 소멸");
}
}
struct Person
{
public string Name;
public int Age;
public void PrintInfo()
{
Console.WriteLine($"Name: {Name}, Age: {Age}");
}
}
Person person;
person.Name = "John";
person.Age = 25;
person.PrintInfo();
// 출력
// Name: John, Age: 25
구조체
클래스
구조체는 작은 크기의 데이터 저장이나 단순한 데이터 구조에 적합하며, 클래스는 더 복잡한 객체를 표현하고 다양한 기능을 제공하기 위해 사용된다.