-
24년 4월 30일 TIL공부 기록 2024. 4. 30. 23:47
인터페이스에 대해 짧게
- 인터페이스는 오버라이드를 사용 하지 않아도 됨.
- 인터페이스 참조형으로 만들어서 자식개체의 값을 넣어줄 수 있음. 이로 인해 리스트나 배열을 만들 때 좋은 효율을 낼 수 있음. 그리고 그것을 Is 연산자로써 더 높은 효율을 뽑을 수 있다.
- 인터페이스는 자동으로 퍼블릭, 클래스는 자동이 private
- 메서드를 만들고 파라미터에 인터페이스 참조형을 넣으면 상속 받은 자식객체를 넣는 방법으로도 활용 가능.
- 변수는 선언 불가, 인스탄스 필드 생성 불가. 속성은 만들 수 있다(프로퍼티)
- 상속을 할 때 클래스와 같이 상속 가능, 클래스는 하나의 클래스와 여러가지의 인터페이스를 동시에 상속 받을 수 있음.
- 인터페이스끼리 서로 상속도 가능함
델리게이트, Delegate 에 대해서
델리게이트란 클래스 내에 메서드들을 관리 하게 하는 기능이라고 할 수 있다.
델리게이트란 클래스를 만들어 주고 그걸 변수로써 만들어 준 다음에 그 변수에 메서드인 값들을 넣을 수가 있다.
그러면 그 델리게이트 변수 하나만 작동을 해서 여러가지의 메서드들을 실행 할 수 있게 되는 것이다.
Delelgate의 형식.( 사용 방법 )
public delegate void 델리게이트이름( 매개변수 ); <- 델리게이트를 만들어 준다.
델리게이트이름 변수명 <- 변수로 만들어 준다.
후에 델리게이트에 함수들을 추가 하고 싶다면 변수 += 메서드명; 를 하거나 -=로 메서드를 뺄 수도 있다.
주의 할 점은 이 델리게이트는 메서드를 포함 하고 있지 않더라도 실행이 될 수 있게 되는데 이 경우 null오류가 발생이 된다. 이 부분을 보완 하기 위해 코드를 보완 해줘야 한다.
if ( 변수명 != null ) 변수명 () ;
델리게이트를 실행 할 때 if 조건문을 사용 해서 보완 할 수가 있다.
왜 사용 하는 가에 대해서 말을 한다면 여러가지에 메서드들이 동일한 조건에 실행을 한다던가 파라미터에 값이 동일한 값으로 실행 되는 메서드들이 여러 개가 있을 때 유용하다. ex) 힘 5증가, 체력 5증가, 방어력 5증가 -> 델리게이트변수명(5);
이벤트, event 에 대해서
이벤트는 델리게이트와 비슷하다. 델리게이트가 클래스에 있는 메서드들을 관리 하는 거라면 이벤트는 다른 클래스에 있는 메서드들도 관리를 할 수 있게 해준다.
형식은 조금 다르다.
public static ( 보통 다른 클래스에서 접근을 하기에 스태틱을 쓴다 ) event 만들어져있는델리게이트참조형! 변수명;
파라미터는 델리게이트를 만들 때 입력을 해뒀으니 이벤트 변수를 만들 때 따로 적지 않는다.
이 외에 방법은 델리게이트와 같다.
그리고 특정한 상황에서 이벤트 메서드를 실행 하게 할 수가 있다.
델리게이트와 이벤트는 복잡한 코드의 연결을 간단하게 할 수 있다.
무명메서드와 람다식 에 대해서
델리게이트를 사용 하다 보면 함수를 하나 더 추가를 해야 하는데, 굳이 따로 만들기에는 번거로울 정도인 경우가 있다.
그럴 때 활용 하는 것이 무명 메서드이다.
델리게이트에 메서드를 추가 하는 것이고 델리게이트를 실행 할 때 같이 실행이 된다.
형식은 이렇다.
델리게이트형변수 += delegate (매개변수) { 실행내용 } ;
이렇게 아주 간단하게 델리게이트에 메서드를 추가 할 수 있는 게 무명 메서드이다. 이 무명 메서드는 델리게이트에서만 호출이 가능하다.
그런데 이 무명메서드를 보면 좀 복잡 하다고 볼 수 있다. 그리고 더 간단하게 구현을 할 수가 있는데 그 것이 바로 람다식이다. 람다식은 무명메서드와 동일한 기능이라고 보면 되는데 길이의 차이라고 보면 된다.
람다식의 형식
델리게이트형변수 += ( 매개변수 ) => {실행내용}
뭔가 훨씬 깔금하고 가독성이 좋아 보인다. 이게 람다식이다.
메서드를 구현 하는 것이다 보니, 파라미터를 적절히 활용 할 수 있게 짤수 있고, 리턴형식으로도 만들 수 있을 것이다. 잘 구상 해서 만들도록 하자.
프로퍼티 에 대해서
다른 클래스에 있는 필드의 값에 접근 할 수 있게 해주는 메서드형식과 비슷한 속성이다. 은닉성이 좋고, 코드를 칠 때 스패너모양이 나오는 건 프로퍼티다.
사용 방법
1. int Name{ get; set;} 바로 프로퍼티를 만드는 것. 나중에 생성자를 통해 간편하게 초기화를 할 수 있다.
2.
int age
public int Age(int value)
{
get{ return name;}
set { age = value }
}
2번과 같은 경우를 보면 프로퍼티의 명이 Name으로 대문자로 돼 있는 걸 볼 수가 있다. 이 것은 필드의 변수명과 다르게 하기 위함이고 왜 다르게 하냐고 물어본다면 지금 생각 안 나니 pass.
그리고 중요한 것은 set을 할 때 value 라는 값으로 넣어줘야 한다. 그 이유는 value 자체도 누군가가 만들어 놓은 C#의 기능이기에 우리가 저렇게 사용 할 수가 있는 것이다.
그리고 우리는 get이나 set을 if 조건문이나 다른 코드들을 사용 해서 유효성 테스트를 거치고 나서 get이나 set을 할 수 있게 할 수도 있다. 보통 set은 같은 클래스 안에서만 수정을 하게 하기 위해서 private로 해두는 것이 좋다.
사용방법
get -> 클래스명.Age , set -> 클래스명.Age = 10;
인덱서에 대해서
우린 다른 클래스에 있는 배열을 사용 할 때, 클래스명.배열이름[] 이런 식으로 사용을 한다.
하지만 보기에 조금 지저분해 보일 수 있다.
이걸 간단하고 깔금하게 보이게 할 수 있는데 이것이 인덱서라는 기능이다.
프로퍼티의 일종이라고 볼 수 있는데, 이 기능을 사용 하면 우리는 클래스명. 배열이름 [ ] 이렇게 해서 배열에 접근 하는 것이 아니라, 변수명[] 이런 식으로 배열에 접근을 할 수 있게 된다. this를 통해서 구현을 한다.
인덱서의 형식
배열이 있는 클래스
{
자료형[] 변수명 = new 자료형 [ 10 ] ;
public 자료형 this[ 자료형 index ]
{
get { return 변수명 [ index ]; }
set { 변수명[ index] = value; }
}
}
이렇게 만들어 주고 배열이 있는 클래스형 객체를 생성 한 후에 그 객체의, 변수명 [ ] 만 적어도 그 배열에 접근을 할 수가 있게 된다. get, set을 할 수가 있게 되는 것이다.
하지만 이 때 주의 해야 할 부분이 있다. 만약 객체를 생성 하고 배열의 값을 가져오거나 값을 넣어줄 때 실제 만들어져 있는 배열인덱스보다 더 많은 배열크기로 실행을 해도 오류가 나질 않는다.
ex) 실제 배열 A [5] , 객체로 만들고 사용 할 때 Abv라는 이름의 변수[7]
실제 배열은 5개 밖에 없는데 7개로 사용을 해도 오류가 바로 나타나지 않는 다는 것이다.
이 부분으로 인해 우리는 코드를 보완 해줄 필요가 있다.
if 조건문을 사용 해서 인덱스의 크기를 맞게 했을 때만 get, set이 작동 하도록 하게 하자.
if( index >= 배열변수명.Length)
이 조건문을 get, set 앞에 넣어주면 된다.
get { if( index >= 배열변수명.Length) else return 변수명 [ index ]; }
set { if( index >= 배열변수명.Length) else변수명[ index] = value; }
하지만 여기서도 또 주의 해야 할 점이 있는데, get 은 반드시 리턴이 돼야 한다. 그로 인해 if가 참일 경우일 때도 리턴 값을 넣어주도록 하자. 의미 없는 0으로 넣으면 된다.
형식매개변수 T에 대해서
우리는 같은 기능을 실행 하는데 자료형만 다른 경우가 있을 수 있다.
그럴 때 형식매개변수를 통해서 효율적으로 작업을 할 수 있게 된다.
예시)
메서드형식
void 함수이름<T> (T value)
{
print (value)
}
이런 식으로 형식매개변수를 활용을 해준다면 우리는 프린트라는 같은 기능을 실행 할 때 스트링 따로 인트형 따로 만들어 줄 필요 없이, 형식매개변수만 변경을 해줌으로써 다르게 실행을 할 수 있게 된다.
그리고 더 나아가 클래스에 형식매개변수를 만들어 줄 수도 있는데 그건 더욱 강력한 기능이 될 수도 있다.
클래스형식
class<T>
{
public T a;
public T b;
public void Abc( T value );
}
이런 식으로 T형식 매개변수를 가진 클래스가 필드와 메서드들을 갖고 있다고 할 때 우린 이 클래스를 인스탄스 할 때 형식매개변수에 형태를 결정 해줌으로써 변수들과 메서드들이 각 상황에 맞는 상태들로 만들어 줄 수가 있게 된다.
클래스를 만들 때 형식 매개변수에 스트링을 넣으면 그 클래스에 T들은 모두 스트링 형식이 되는 것이다.
이것은 우리가 인트인지 스트링인지, 클래스형식인지 인터페이스 형식인지 등 여러가지에 형식을 넣을 수 있고 그 넣는 것만으로도 동일한 작업을 안 하게 되는 것이니 잘 설계만 한다면 매우 유용한 기능이다.
여기서 T는 Type의 약자이며 다른 것으로 써도 되지만 일반적으로 T로 적는 것이 관례이다.
그리고 value라고 적혀 있는 것은 위에서도 말 했듯이 누군가가 만들어 놓은 기능이므로 저렇게 사용 할 수가 있는 것이다.
구조체(struct) 에 대해서
구조체에 대해서 말을 한다면 클래스와 비교를 먼저 해야 할 것이다.
일단 예전에는 클래스가 없었다. 스트럭트라는 것이 먼저 생겼고 나중에 업데이트 되면서 클래스가 만들어진 것이다.
구조체는 구버젼, 클래스는 신버젼이라고 생각을 하면 된다.
구조체를 계속 사용 하는 이유도 옛날에 만들어 둔 것들이 구조체여서 호환성 이유로 남겨두는 것이다.
그러면 클래스만 사용 하면 되는 것이지 않냐 라고 생각 할 수 있다. 하지만 아니다.
그럼에도 구조체가 사용 되는 경우가 있다.
하지만 그걸 구분 하려면 심화적인 지식이 필요하다.
지금 내 수준에서 이걸 구분 하려고 노력 하는 것은 비효율적이다. 지금의 나는 클래스와 구조체가 거의 동일한 녀석이다라고만 알고 있으면 된다. 그리고 약간의 차이점만 알면 된다.
구조체는 구조체에서 선언은 가능 하지만 할당은 불가능 하다.
클래스는 할당까지 가능 하다.
클래스는 다른 클래스에서 할당을 하려면 객체를 생성 해서 할당을 해야한다. new
구조체는 내부적으로 new 행동을 실행을 해주기 때문에 따로 적어주지 않아도 할당을 해줄 수 있다.
int 자료형 같은 것들 경우에도 struct형으로써 int a = new int(); 가 내부적으로 실행을 해주는 것이다.
구조체는 값타입, 클래스는 주소타입이다.
값타입은 바로 꺼내올 수 있는 느낌이고, 주소타입은 찾아와야 하는 느낌이다.
일단 이정도 차이만 알고 구조체는 마무리 하면 될 것이다.
잡다한 것
생성자를 만들 때 컨트롤 . 을 통해 간단하게 만들 수 있다.
'공부 기록' 카테고리의 다른 글
24년 5월 2일 TIL (1) 2024.05.02 24년 5월 1일 TIL (4) 2024.05.02 24년 4월 29일 TIL (0) 2024.04.29 24년 4월 28일 TIL (1) 2024.04.28 24년 4월 27일 (0) 2024.04.27