- 관련된 데이터와 기능을 하나의 단위로 묶는 것!
- 클래스를 사용하여 데이터와 메서드를 캡슐화하여 정보를 은닉, 접근을 제한함으로써 안정성과 유지보수성을 높인다.
- 상속은 기존의 클래스를 확장하여 새로운 클래스를 만드는 것!
- 부모 클래스의 특성과 동작을 자식 클래스가 상속받아 재사용할 수 있다.
- 코드의 중복을 줄이고, 클래스 간 계층 구조를 구성하여 코드의 구조화, 유지보수를 용이.
- 다형성은 하나의 인터페이스나 기능을 다양한 방식으로 구현하거나 사용할 수 있는 능력.
- 하나의 메서드 이름이 다양한 객체에서 다르게 동작할 수 있는 것! 오버로딩, 오버라이딩을 통해 구현.
- 유연하고 확장 가능한 코드 작성을 가능케 하며, 코드의 가독성과 재사용성을 높인다.
- 클래스나 인터페이스를 사용하여 실제 세계의 개념을 모델링, 필요한 부분을 정의.
- 세부 구현 내용을 감추고 핵심 개념에 집중함으로써 코드의 이해, 유지보수 용이.
- 객체는 클리스로부터 생성된 실체. 데이터와 해당 데이터를 조작하는 메서드를 가지고 있다.
- 객체는 상태(데이터)와 행동(메서드)를 가지며, 실제 세계의 개체가 개념을 모델링한다.
- 객체들 간의 상호작용을 통해 프로그램이 동작, 모듈화와 재사용성 높인다.
→ 붕어빵을 만들기 위한 붕어빵 틀이라 생각하면 좋다.
→ 붕어빵 틀로 비교하면, 객체는 붕어빵이라 할 수 있다. 붕어빵 틀(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
// 구조체를 생성하기 Person person1; person1.Name = "John"; person1.Age = 25; person1.PrintInfo(); // 클래스를 생성하기 Person p = new Person(); p.Name = "John"; p.Age = 25; p.PrintInfo(); // 출력: Name: John, Age: 25
위의 코드에서 볼 수 있듯이 구조체는 값 형식이기 때문에 Person person1;
의 형태로 선언을 한다.
반면 클래스의 경우, 참조 형식이기 때문에 Person p = new Person();
와 같이 new를 사용하여 선언하는 것을 볼 수 있다(동적 할당).
구조체의 경우, person1이라는 변수가 실제로 생성이 되지만 클래스는 실제 Person의 주소값을 가지는 p를 선언한다.
클래스의 접근 권한을 지정하여 데이터를 보호할 수 있다.
접근 제한자는 클래스, 필드, 메서드 등의 접근 가능한 범위를 지정하는 키워드.
접근 제한자는 클래스의 캡슐화를 제어하는 역할을 한다.
class Person { public string Name; // 외부에서 자유롭게 접근 가능 private int Age; // 같은 클래스 내부에서만 접근 가능 protected string Address; // 같은 클래스 내부와 상속받은 클래스에서만 접근 가능 }
class Player { // 필드 선언 private string name; private int level; }
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();
해당 코드에는 눈에 보이지 않는 디폴트 생성자가 생성되어 있다.
public Person() { }
와 같은 형식의 생성자가 자동으로 생성되게 된다. 이 생성자는
new Person()
과 같다.
// 생성자 오버로딩을 하는 경우 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); // 매개변수를 받는 생성자 호출
class Person { private string name; public Person(string newName) { name = newName; Console.WriteLine("Person 객체 생성"); } ~Person() { Console.WriteLine("Person 객체 소멸"); // C#의 버전이 올라감에 따라 프로그램이 종료될 때 소멸자 호출을 보여주지 않는다고 함... } }
[접근 제한자] [데이터 타입] 프로퍼티명 { 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"; // Name 프로퍼티에 값 설정(Name의 set이 호출됨) person.Age = 25; // Age 프로퍼티에 값 설정(Age의 set이 호출됨) Console.WriteLine($"Name: {person.Name}, Age: {person.Age}"); // Name과 Age 프로퍼티(Name, Age의 get이 호출됨)
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 { // 나이에 0 또는 음수 값이 설정될 경우를 방지할 수 있다 → 유효성 검사 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 프로퍼티에 접근하여 값을 출력합니다.
[접근 제한자] [데이터 타입] 프로퍼티명 { get; set; }
ex)
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}"); // 값을 읽어 출력