: 멤버란 클래스의 구성 요소로, 아래의 종류가 있습니다.
→ 필드, 상수, 프로퍼티, 메소드, 이벤트, 연산자, 인덱서, 생성자, 종료자, 네스티드 타입
class User
{
int _id;
string _name;
System.DateTime _birthday; // 내장타입 아님
}
class User
{
const int _id;
const string _name;
const System.DateTime _birthday; // 내장타입이 아니기에 불가능
}
class A
{
private readonly int _num;
private readonly System.DateTime _createTime;
public A
{
_num = 10; // 가능
_createTime = DateTime.Now; // 가능
}
public A(int n)
{
_num = n; // 가능
_createTime = DateTime.Now; // 가능
}
// 복사 생성자(Copy Constructor)의 예시
public A(A other)
: this(other._num)
{
}
public void Foo()
{
_num = 10; // 생성자가 아닌 곳에서 할당하려 했으므로 오류 발생
}
}
class Warrior
{
private int _hp = 100;
private int _atk = 10;
public void TakeDamage(int damage)
{
_hp = Math.Max(0, _hp - damage);
if(_hp == 0)
{
Die();
}
}
public void Die() => System.Console.WriteLine("으아악");
}
1) 오버로딩이란?
2) 시그니처 (Signature)
public void Foo(int a) { }
public void Foo(double a) { } // 가능, 매개변수의 타입이 달라짐
public void Foo(int b) { } // 불가능, 결국 int 타입의 매개변수 하나로 같은 형식
public int Foo (int a) { } // 불가능, 반환값만 바꿔선 안됨
private void Foo (int a) { } // 불가능, 접근 수준만 바꿔선 안됨
3) 헬퍼 함수
class Regex
{
// 헬퍼 함수
public static int Count(string input, string pattern)
{
Count(input, pattern, RegexOption.IgnoreCase);
}
// 함수의 원형
public static int Count(string input, string pattern, RegexOptions options)
{
...
}
}
1) 이미 존재하는 타입(클래스)에 추가한 프로그래머의 메소드를 의미합니다.
2) 확장 메소드는 정적 메소드(static)이어야 합니다.
3) 첫번째 매개변수가 this 포인터 확장시킬 타입(클래스) 매개변수명 여야합니다.
4) Regex 클래스에 Count( ) 메소드를 추가해 사용하는 예제
static class RegexExtentions
{
public static int Count(this Regex regex, string str)
{
MatchCollection matches = regex.Matches(str);
return matches.Count;
}
}
class Program
{
public static void Main()
{
Regex regex = new Regex(@"(pAPp)");
string input = "ApPApPpAPpApPAp";
regex.Count(input); // 확장 메소드 Count를 호출해 사용
}
}
class Character
{
private int _hp;
public void SetHp(int newHp) => _hp = newHp; // Setter
public in GetHp() => _hp; // Getter
}
1) Getter
: 데이터를 수정할 수 있는 메소드
2) Setter
: 데이터에 접근할 수 있는 메소드
1) c#에서 Getter와 Setter를 더욱 편리하게 사용하기 위해 제공하는 기능
→ 즉, 프로퍼티 또한 메소드입니다.
2) 일부 프로퍼티 접근자의 접근 수준을 다르게 할 수 있습니다.
class Character
{
public int HP { get; set; }
public int Mp { get; private set; }
}
1) 클래스의 객체를 생성할 때, 객체의 데이터를 초기화하는 메소드 입니다.
2) 생성자는 new 연산자와 함께 호출됩니다.
3) 생성자는 반환값이 없으며, 클래스의 이름과 같습니다.
4) 생성자를 정의하지 않을 경우, 컴파일러가 매개변수가 없는 생성자를 자동으로 생성합니다.
5) 별도로 지정하지 않는 경우, 모든 데이터는 기본값으로 초기화되며 초기값이 있는 경우 그 값을 사용합니다.
6) 매개변수가 있는 생성자를 하나라도 정의한 경우, 매개변수가 없는 생성자는 자동생성되지 않습니다.
1) 생성자 또한 메소드의 일종으로, 오버로딩이 가능합니다.
2) 생성자 오버로딩 시 다른 생성자를 호출할 수 있으며 이 때 this라는 키워드를 사용합니다.
3) this 키워드 사용시 콜론(:) 사용에 유의합니다.
Class Coord
{
public Coord()
: this(0, 0) // 1. 매개변수가 int 타입 두개인 생성자 호출
{
// 3. int 타입 두개인 생성자 부분 실행 후 여기로 넘어와서 이 블록 내용까지 실행
}
public Coord(int x, int y) // 2. 실행흐름이 여기로 이동
{
X = x;
Y = y;
}
}
public void Main()
{
Coord coord = new Coord(); // 매개변수가 없는 생성자 호출할 경우 실행흐름
}
인스턴스들의 데이터는 서로 영향을 주고받지 않고, 독립적입니다.
독립적인 데이터를 사용할 수 있는 핵심적인 이유가 바로 this 포인터 입니다.
class Character
{
private int _hp = 100;
public void TakeDamage(int damage) => _hp -= damage;
}
Character character1 = new Character();
Character character2 = new Character();
character1.TakeDamage(10);
→ 위와 같은 코드를 실행했을 때, 사실 TakeDamage는 명시적으로 작성된 인수인 10과 함께 character1의 주소 또한 인수로 전달합니다.
→ _hp -= damage;는 사실 this._hp -= damage; 와 같으며 this는 (character1의 주소를 전달받아) 현재 메소드를 호출한 인스턴스를 참조하기 때문에, 인스턴스의 데이터를 구분하여 동작할 수 있는 것입니다.
→ this 포인터는 인스턴스 메소드에서만 유효합니다.
1) static 한정자를 사용해 멤버를 정적으로 만들 수 있습니다.
2) 정적 멤버란, 인스턴스끼리 공유하는 멤버를 의미합니다.
class Character
{
private static int s_hp = 100;
public void TakeDamage(int damage) => s_hp -= damage;
}
Character character1 = new Character();
Character character2 = new Character();
character1.TakeDamage(10);
character2.TakeDamage(10);
Console.WriteLine(Character.s_hp); // 80이 출력된다.
1) 정적 필드는 런타임에 초기화 됨
2) 정적 필드를 초기화하기 위해 정적 생성자를 사용할 수 있습니다.
3) 정적 필드는 접근 한정자 및 매개변수를 가지지 않습니다.
4) 오직 한가지만 존재하며, 직접 호출할 수 없습니다.
5) 정적 필드는 스택 혹은 힙 영역을 사용하지 않으며, 데이터 영역을 사용합니다.
6) 정적 멤버만 모아놓기 위해 정적 클래스를 만들 수 있으며, 이 경우 인스턴스를 만드는 것이 불가능해집니다.
참고자료