- Virtual(가상) : 하나의 기능을 하는 완전한 클래스, 파생 클래스에서 상속해서 추가적인 기능 추가 및 재정의 가능(필수아님).
- Abstract(추상) : 여러개의 파생 클래스에서 공유할 기본 클래스의 공통적인 정의만 하고, 파생 클래스에서는 무조건 재정의를 해야한다(필수).
- Interface : Abstract와 비슷하지만, 멤버변수를 사용할 수 없다. 서로 다른 계층이나 타입이더라도 같은 기능을 추가하고 싶을 때 사용한다.
- 구조체는 상속을 할 수 없다.
- 클래스 객체는 Heap에 할당이 되지만, 구조체 객체는 Stack에 할당된다.
- 상속 : base Class로 부터 필드, 메서드 등을 그대로 물려 받아 새로운 derived Class를 만드는 것.(sealed 한정자로 클래스의 상속을 봉인할 수 있다.)
- 다형성 : 객체가 여러 형태를 가질 수 있음을 의미한다.
- Array는 동적 할당이 불가능하고, List는 동적 할당이 가능하다.
- 즉, 데이터를 할당할 시 데이터의 크기가 정해져 있으면 Array 아니면 List를 사용하는 것이 좋다.
- 프로젝트에서 협업을 하다 보면 불가피하게 클래스의 이름이 중복될 수 있다. 이를 방지 하기위해서 namespace를 사용한다.
- 하나의 파일에 하나의 클래스를 작성한다고 해도 그 클래스의 크기가 엄청나게 길어지는 경우가 있어 가독성이 떨어질 수 있다. 이 때 파일을 분할해서 동일한 클래스를 작성하고 싶을 떄, partial 키워드를 사용한다.
- SOLID 원칙
단일책임원칙 : 클래스는 단 하나의 목적을 가져야하며, 클래스를 변경하는 이유도 단 하나의 이유여야한다.
개방-폐쇄의 원칙 : 확장에는 열러있고, 변경에는 닫혀있어야한다.
리스코프 치환 원칙 : 상위 타입의 객체를 하위 타입으로 바꾸어도 동일하게 동작해야한다.
인터페이스 분리 원칙 : 객체는 이용하지 않는 매서드에 의존하지 않도록, 인터페이스를 분리해야한다.
의존관계 역전 원칙 : 추상화에 의존해야지, 구체화에 의존하면 안된다.
- 캡슐화 : 연관있는 변수와 매서드를 묶어주는 작업. 클래스의 접근 제한을 하고, 객체 내에서만 접근 가능하도록 정보를 은닉한다.
- 추상화 : 객체에서 필요한 공통된 부분을 추출.
- 상속 : 부모 클래스로부터 공통된 변수와 함수, 인터페이스를 그대로 물려받는다.
- 다형성 : 같은 종류의 클래스가 하나의 메세지에 대해 서로 다른 행동을 한다.(오버로딩, 오버라이딩)
- 전역 변수 : Heap매모리에 저장되며, 함수 외부에서 선언된다. 프로그램이 종료되기 전까지는 파괴되지 않는다.
- 지역 변수 : Stack메모리에 저장되며, 함수 내부에서 선언된다. 해당 함수가 종료되면 같이 파괴된다.
- 차이점 : delegate는 public한정자로 선언하면 클래스 외부에서 호출이 가능하다. 하지만 event는 public한정자로 선언해도 클래스 외부에서는 호출이 불가능하다.
- event는 객체의 상태 변화나 사건의 발생을 알리는 용도로 사용이 되고, delegate는 callback의 용도로 사용된다.
- 기본적으로 값 형식은 Stack에 참조형식은 Heap에 할당된다.
- 참조 형식의 경우 그것이 포함한 값 형식은 자신의 인스턴스 내에 포함된다.
- 내부에 참조 형식의 필드가 있으면 별도의 Heap주소를 가리키는 주소값만을 담고 있다.
- Boxing : 값 타입의 객체를 참조 타입으로 변환하는 작업
Stack에 있던 값 타입의 객체를 Heap으로 이동할 때, 복사가 한번 일어난다.
Heap에 복사된 이 영역을 참조 타입이 가리키게 되는 일을 수행한다.
- UnBoxing : 참조 타입을 값 타입으로 변환하는 작업
Heap에 있던 데이터를 Stack으로 복사
value를 ref타입으로 Boxing한다. Stack에 있던 value를 Heap으로 복사 후 주소값을 할당함.
- 세대별 GC
0세대 : GC를 한번도 겪지 않은 갓 생성된 객체가 대상
1세대 : GC를 1회 겪은 객체가 대상
2세대 : GC를 2회 이상 겪은 객체가 대상(전체를 의미)
- 세대가 낮은 메모리부터 메모리 해제를 해준 다음 메모리 컴펙션을 해준다.
- 2세대 GC를 할 시 Full Garbage Collection이라 하고 전체 Heap에 대하여 GC하는 것을 의미한다.
- 세대를 나누는 근거
최근에 생성된 객체일수록 생명주기가 짧을 가능성이높고, 오래된 객체일수록 생명주기가 길 가능성이 높습니다.
최근에 생성된 객체끼리는 서로 연관성이 높을 수 있으며, 비슷한 시점에 자주 액세스 됩니다.
일부분 Heap에 대해 GC를 하는 것이 전체 GC를 하는 것 보다 빠릅니다.
- LOH : Large Object Heap으로 CLR(Common Language Runtime)에서 용량이 큰(83KB이상) 객체에 사용되는 Heap
- SOH : 그 이하 평소에 사용되는 Heap
LOH는 GC시 2세대로 간주하고, 메모리 해제 후 메모리 컴펙션을 진행하지 않으므로, 메모리 내부 단편화가 발생할 수 있다.