C#/클래스와 객체지향
C# 클래스와 객체지향 - 16. 하이딩과 오버라이딩
tita
2024. 5. 29. 16:08
하이딩은 부모 클래스와 자식 클래스에 동일한 이름으로 멤버를 만들 때 발생합니다.
그런데 하이딩과 같은 형태로 메서드를 작성하고 앞에 virtual 키워드를 붙이면 오버라이딩이라 부르게 됩니다.
오버라이딩은 부모 클래스에 있는 메서드를 자식 클래스에서 다시 구현하는 것을 의미합니다.
하이딩과 혼동하지 않도록 주의해야 합니다.
[new 메서드]
부모 클래스의 멤버와 자식 클래스의 멤버가 서로 이름이 같으면 하이딩됩니다.
그리고 하디이한다는 것을 명확하게 표시하고자 메서드 이름 앞에 new 키워드를 붙여줍니다.
체지향 15. 섀도잉과 하이딩 마지막 코드에서 났던 에러를 다음과 같이 해결할 수 있습니다.
class Program
{
class Parent
{
public int variable = 10;
public void Method()
{
Console.WriteLine("부모의 메서드");
}
}
class Child : Parent
{
// new 키워드를 사용해 변수를 하이딩하겠다고 선언합니다.
public new string variable = "hiding";
// new 키워드를 사용해 메서드를 하이딩하겠다고 선언합니다.
public new void Method()
{
Console.WriteLine("자식의 메서드");
}
}
static void Main(string[] args)
{
Child child = new Child();
child.Method();
((Parent)child).Method();
}
}
[virtual과 override 메서드]
오버라이딩을 간단하게 표현하면 '부모의 메서드를 덮어씌운다'고 할 수 있습니다.
사용 구문을 살펴보겠습니다.
class Program
{
class Parent
{
// 부모의 메서드에 virtual 키워드 적용합니다.
public virtual void Method()
{
Console.WriteLine("부모의 메서드");
}
}
class Child : Parent
{
// 자식의 메서드에 override 키워드 적용합니다.
public override void Method()
{
Console.WriteLine("자식의 메서드");
}
}
static void Main(string[] args)
{
Child child = new Child();
child.Method();
((Parent)child).Method();
}
}
/*
[실행 결과]
자식의 메서드
자식의 메서드
*/
이렇게 실행하면 이전에 new 키워드를 사용한 것과는 다른 결과가 나옵니다.
이는 자식의 메서드가 부모 메서드를 완전히 덮어씌워 부모로 클래스형을 변환했으므로, 호출을 해도 덮어씌운 것 때문에 다른 결과가 나오는 것입니다.
이처럼 오버라이딩하면 클래스형을 어떻게 변환해도 자식에서 다시 정의한 메서드가 호출됩니다.
그렇다면 이러한 오버라이딩을 사용하는 경우는 어떤 경우인지 알아보겠습니다.
class Program
{
class Animal
{
public virtual void Eat()
{
Console.WriteLine("냠냠 먹습니다.");
}
}
class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("강아지 사료를 먹습니다.");
}
}
class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("고양이 사료를 먹습니다.");
}
}
static void Main(string[] args)
{
List<Animal> Animals = new List<Animal>()
{
new Dog(), new Cat(), new Cat(), new Dog()
};
foreach(var item in Animals)
{
item.Eat();
}
}
}
/*
[실행 결과]
강아지 사료를 먹습니다.
고양이 사료를 먹습니다.
고양이 사료를 먹습니다.
강아지 사료를 먹습니다.
*/
위와같은 상황에서 virtual 과 override 를 사용하지 않으면 오로지 부모의 메서드만 호출됩니다.
하지만 오버라이딩을 사용하면 위의 결과가 나오게 됩니다.