내일배움캠프/TIL

[내배캠][Unity6기][TIL] C# 문법 종합 강의 3주차

binary는 호남선 2024. 9. 21. 21:42

Preview

- 구조체와 클래스
- 소멸자 (Destructor)
- 프로퍼티 (Property)
- 오버라이딩 (Overriding) 과 오버로딩(Overloading)
- 가상메서드 (Virtual Method)


구조체와 클래스

  구조체 클래스
형식 참조
메모리 영역 스택
상속 여부 상속 불가 상속 가능

소멸자 (Destructor)

- 객체가 소멸되는 시점에 자동으로 호출되는 특별한 메서드

- C#에서는 가비지 컬렉터가 자동으로 관리하므로 유저의 명시적 소멸자 호출 지양

- 호출 주체가 사용자가 아니므로 오버로딩 불가능

프로퍼티 (Property)

- 클래스의 멤버로, 필드와 메서드의 조합

- get(값을 반환), set(값을 설정) 접근자로 필드에 간접적으로 접근

- 코드 안정성과 가독성 향상

 

[ 접근 제한자 적용 & 유효성 검사 예제 ]

class Cat
{
    private string name;
    private int age;

    public string Name
    {
        get { return name; }
        private set { name = value; }
    }

    public int Age
    {
        get { return age; }
        set
        {
            if (value >= 0)
                age = value;
        }
    }
}
internal class Program
{

    static void Main(string[] args)
    {
        Cat cat = new Cat();
        // ERR[CS0272] : 해당 프로퍼티에 접근 불가
        cat.Name = "Yuumi";
        // 유효성 검사에 의해 나이 값 미설정됨
        cat.Age = -10; 
    }
}

[ 자동 프로퍼티 예제 ]

class Cat
{
    public string Name { get; set; }
    public int Price { get; set; }
}
internal class Program
{
    static void Main(string[] args)
    {
        Cat cat = new Cat();
        cat.Name = "Yuumi";
        cat.Price = 260; 
    }
}

참고 : https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/using-properties

 

오버라이딩 (Overriding) 과 오버로딩(Overloading)

- 오버라이딩 : 부모 클래스에서 정의된 메소드를 자식 클래스에서 재정의 (상속 관계에서 발생)

- 오버로딩 : 동일한 메서드 이름으로 매개 변수의 개수, 타입, 순서를 다르게 하여 중복정의

(매개 변수의 이름, 반환 타입과 값은 상관x)

가상메서드 (Virtual Method)

- 하위 클래스에서 재정의할 수 있는 상위 클래스의 메서드

- 상위 클래스에서는 virtual 키워드와 정의됨

- 하위 클래스에서 재정의할 때는 override 키워드 사용

※ virtual 키워드는 자식 메서드에서 이 부모 메서드가 재정의 되었을 수 있으니(실형태 다를 수 있으니) 확인하게 함

[ 잘못된 예시 ]

public class Animal
{
    public void MakeSound()
    {
        Console.WriteLine("Animal makes sound.");
    }
}
public class Dog : Animal
{
    public void MakeSound()
    {
        Console.WriteLine("BowWow");
    }
}
public class Cat : Animal
{
    public void MakeSound()
    {
        Console.WriteLine("Meow");
    }
}
internal class Program
{
    static void Main(string[] args)
    {
        // 참조 형태와 실형태 같을 때
        Dog dog = new Dog();
        dog.MakeSound();    // BowWow
        Cat cat = new Cat();
        cat.MakeSound();    // Meow
        // 의도한대로 동작

        // 참조 형태와 실형태 다를 때
        List<Animal> list = new List<Animal>();
        list.Add(new Dog());
        list.Add(new Cat());

        foreach (Animal animal in list)
        {
            animal.MakeSound();
        }
        // Animal makes sound.
        // Animal makes sound.
        // Animal 이라는 하나의 참조형태로 관리하므로
        // 가까운 부모 클래스의 메서드가 먼저 호출됨
    }
}

[ 올바른 예시 ]

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Animal makes sound.");
    }
}
public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("BowWow");
    }
}
public class Cat : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Meow");
    }
}
internal class Program
{
    static void Main(string[] args)
    {
        List<Animal> list = new List<Animal>();
        list.Add(new Dog());
        list.Add(new Cat());

        foreach (Animal animal in list)
        {
            animal.MakeSound();
        }
        // BowWow
        // Meow

        // Animal이라는 하나의 참조형태로 관리하지만
        // virtual 키워드로 실형태를 확인
    }
}