23.01.30.(월) - 클래스 심화(메소드, 속성, 헬퍼 함수, 생성자, readonly, this, 정적 멤버, 확장 메소드, 엔덱서)

김도익·2023년 1월 30일
0

C#

목록 보기
20/29

멤버

  • 클래스는 나만의 타입을 만들 수 있는 도구입니다. 클래스는 여러 가지 멤버(Member)로 표현됩니다. 멤버의 종류에는
    아래와 같습니다.

  • 필드
    상수
    프로퍼티
    메소드
    이벤트
    연산자
    인덱서
    생성자
    종료자
    네스티드 타입

  • 이 중에서 필드 / 상수 / 메소드 / 프로퍼티 / 생성자를 먼저 배워보겠습니다.

필드

  • 필드는 클래스 범위에 선언된 변수로 해당 타입을 구성하는 데이터입니다.

상수

  • 변수 말고 상수로 멤버 추가가 가능합니다. 단, 필드와 달리 내장 타입(Object는 예외)만 가능합니다.

메소드

  • 메소드는 함수로 클래스가 할 수 있는 행위를 정의합니다.

  • 클래스를 만들면 보통 필드를 직접 수정한다기보다는 메소드를 호출해 데이터를 조작하는 것이 일반적입니다.

  • 메소드는 같은 이름을 사용할 수 있습니다. 단, 이 경우 시그니처(Signature)가 달라야합니다.

    • 시그니처는 함수의 입력과 출력을 정의합니다.
    • 시그니처는 접근 수준, 한정자, 반환값, 함수의 이름, 함수의 매개변수로 구성됩니다. 같은 이름을 사용하려면 매개변수를 달리하면 됩니다.
  • 이런 기능을 오버로딩(Overloading)이라고 하며, 입력된 데이터를 달리할 때나 헬퍼 함수를 정의하는데 사용할 수 있습니다.


    // Foo, Foo(int a), Foo(double)이 오버로딩입니다.
    // public int Foo()와 public void Foo(int b)는 오류입니다.

  • 옛날 C언어 사용 당시에는 함수마다 이름을 서로 다르게 작명을 했어야 하는 어려움이 있었습니다. 하지만 C#은 오버로딩을 지원해서 작명에 대한 부담감을 덜어줬습니다. 단, 가독성이 있는지, 없는지에 대한 의견은 나뉘지만, 교수님께서는 오버로딩은 좋다고 생각한다는 의견을 내셨습니다.

  • 오버로딩을 하고 싶다면 ‘매개변수’가 달라야합니다. 반환 타입이나, 접근자를 다르게 한다고 해서 오버로딩이 되지 않습니다.

헬퍼 함수

  • 어떤 함수의 매개변수가 복잡하니까 좀 더 간단하게 쓸 수 있게 제공해주는 함수를 헬퍼 함수라고 합니다.

    // 맨 위 Count 함수가 헬퍼 함수

프로퍼티

  • 클래스를 설계할 때는 사용자가 직접 데이터를 건드리지 않고, 주어진 메소드만을 활용해서 간접적으로 데이터를 조작하게끔 만드는 것이 좋습니다. 그래야 사용성이 증대되기 때문입니다.

  • 하지만 가끔은 데이터에 직접 접근할 수 있는 메소드를 정의해야 할 때가 있습니다. 이를 Setter 및 Getter라고 합니다.

  • 하지만 매번 설정자와 접근자를 입력하는 것은 귀찮은 일이기에 C#에서는 편리한 방법을 제공합니다. 바로 ‘Property’입니다.

    // private set은 해당 클래스 내부에서만 변경이 가능합니다.

  • 변수처럼 사용이 가능합니다.

생성자

  • 객체의 데이터를 초기화하는 메서드입니다.

    // 반환값은 따로 없습니다.
    // Class와 이름이 같아야합니다.

  • 생성자는 딱히 정의하지 않아도 상관 없는데, C#이 알아서 매개변수가 없는(Parameterless) 생성자를 만들어내기 때문입니다.

  • 생성자 또한 메소드이기에 오버로딩이 가능합니다. 단, this를 사용해야합니다.

readonly

  • 상수처럼 클래스 타입도 더 이상 수정되지 않길 원한다면 reandonly 한정자를 사용할 수 있습니다.

  • readonly는 필드를 정의할 때 붙일 수 있으며, 해당 필드는 생성자 안에서만 값을 할당할 수 있습니다.

  • 생성자 범위를 벗어나면 값을 할당하지 못합니다.

this

  • 인스턴스끼리는 데이터가 독립적입니다.

  • 헌데 어떻게 이런 일이 가능할까? 여기엔 this 포인터가 있습니다. 사실 필드를 사용할 때 this가 생략되어 있습니다. this는 주소 값이 저장되어 있습니다.

  • 인스턴스 멤버는 전부 this가 생략되어 있습니다.

    • this 포인터는 인스턴스 메소드에서만 유효합니다.

  • this를 명시적으로 작성할 일은 없습니다.
    단, 내부적으로 character1 과 character2를 나눠주는 역할을 하는 것이 this라는 것을 이해하고 있으면 됩니다.

정적 멤버

  • static 한정자를 사용하면 멤버를 정적(static)으로 만들 수 있습니다.

  • 정적 멤버가 되면 인스턴스끼리 공유하는 멤버가 됩니다.

    // static이 없다면 character1 = 90, character2 = 90이어야합니다.
    // 하지만 static을 사용하면 멤버를 공유하기 때문에 100 - 10 - 10 = 80이 되는 것입니다.

  • 정적 멤버는 클래스 이름을 통해서만 접근합니다.

정적 필드를 초기화하기 위해 정적 생성자를 사용할 수 있습니다. 단, 여러 가지 제약 사항이 존재합니다.

  • 접근 한정자 및 매개변수를 가지지 않습니다.

  • 오직 하나만 존재합니다.

  • 직접적으로 호출할 수 없습니다. CLR에 의해서만 자동으로 호출됩니다.

    • 실행 시점을 사용자가 제어할 수 없으며, 다만 첫 인스턴스가 생성되기 전 혹은 정적 멤버가 참조되기 전에는 무조건 호출됩니다.
    • 인스턴스 생성자가 호출되기 전에 정적 생성자가 실행됩니다.

정적 필드는 스택 혹은 힙 영역을 사용하지 않으며 데이터 영역을 사용합니다.

  • 정적 멤버만을 모아놓기 위해 정적 클래스를 만들 수 있습니다. 이 경우 인스턴스를 만드는 것이 불가능해집니다.

Tip 정적 멤버에는 this라는 개념이 없습니다.
왜냐구요??
간단합니다. 정적 멤버는 인스턴스끼리 공유하기 때문입니다!
그러니 this라는 개념이 없는 것입니다.

확장 메소드(Extension Method)

  • 이미 존재하는 타입에 우리의 메소드를 추가할 수 있습니다. 이를 확장 메소드라고 합니다.

  • 확장 메소드를 이용하면 마치 원래 있던 메소드마냥 사용할 수 있습니다.

  • 예를 들어 .NET 7에서 밖에 사용할 수 없는 Regex.Count()를 .NET 6에서 추가한다고 해보겠습니다.

  • 백준 15881번 문제

    // this 쓰지 않으면 그냥 정적 메소드입니다.
    // 확장 메소드와 정적 메소드를 구분할 줄 알아야합니다.
    // 여기서 this는 인스턴스 this랑 다른겁니다. 견문이 넓어지다보면 무엇이 다른지, 이해할 수 있습니다. 견문아 높아져라 얍~!

인덱서

인덱서

  • 클래스 멤버에는 인덱서가 있습니다.

  • 형식 또는 인스턴스 멤버를 명시적으로 지정하지 않고 인덱싱된 값을 설정하거나 검색할 수 있습니다.

  • 인덱서는 접근자가 매개변수를 사용하다는 점을 제외하면 속성과 비슷합니다.

  • 쉽게 말해 클래스의 값을 배열처럼 접근할 수 있도록 해주는 문법입니다.

인덱서 개요

  • 인덱서를 사용하면 배열과 유사한 방식으로 개체를 인덱싱 할 수 있습니다.

  • 접근자는 값 get을 반환합니다. 접근자는 값 set을 할당합니다.

  • this 키워드는 인덱서를 정의하는데 사용됩니다.

  • value 키워드는 접근자가 할당하는 값을 정의하는데 사용됩니다. - > set에서 사용

  • 인덱서는 정수 값으로 인덱싱 할 필요가 없습니다. 특정 조회 매커니즘을 정의하는 방법은 사용자에게 달려 있습니다.

  • 인덱서는 오버로드 될 수 있습니다.

인덱서 정의 방법

  • 한정자 : public, private, protected 등 접근 한정자를 설정합니다.

  • 타입 : 인덱서 반환 타입을 정의합니다. - Object 타입은 지양합시다. 사용하지 않는 것이 좋습니다.

  • this : 현재 클래스에 대해 인덱서를 정의하고 있음을 나타냅니다.

  • int형 인덱스 또는 string명 : 인덱스 위치를 int형 인덱스로 접근할 것인지 또는 string 명으로 접근할 것인지 설정합니다.

인덱서 사용 예시

profile
고급 개발자가 되고 싶어요!

0개의 댓글