가상 메서드
만약 부모 클래스에 모든 메서드를 일반 메서드로 구현하고 상속한 자식 클래스에서 메서드를 오버라이딩했다면
이 자식 메서드를 그냥 자식메서드 자체로 사용했을때는 아무런 문제가 없지만
만약에 자식 클래스를 부모 클래스 타입으로 참조하여 사용하게된다면 이때 오버라이딩한 자식 클래스의 메서드가 아니라
부모 클래스의 메서드가 사용된다
키워드가 없는 오버라이드 : 부모 클래스의 메서드가 자식 클래스에서는 숨겨지고 부모 클래스 타입으로 참조하면 부모 클래스의 메서드가 호출됨
namespace ConsoleApp1
{
class parent
{
public void func()
{
Console.WriteLine("부모 클래스의 func");
}
}
class child :parent
{
public void func()
{
Console.WriteLine("자식 클래스의 func");
}
}
internal class Program
{
static void Main(string[] args)
{
List<parent> list = new List<parent>();
list.Add(new child() );
foreach(parent items in list)
{
items.func();
}
new child().func();
}
}
}
이런 상황을 해결하기 위해서 virtual, override 키워드가 존재한다.
부모 클래스에서 만약 메서드를 정의할때 virtual 키워드를 통해서 정의했다면
자식 클래스에서 해당 메서드를 오버라이딩 할때는 override 키워드를 사용해서 오버라이딩 해야한다.
이렇게 가상 메서드를 오버라이딩 했다면 만약 자식 클래스를 부모 클래스 타입으로 참조해서 메서드를 작동시켜도
vitual 키워드로 작성된 메서드는 자식이 override한 메서드인지 확인하고 override된 메서드가 작동한다.
override 키워드를 사용한 override : 부모 클래스의 메서드가 완전히 대체되어 부모 클래스 타입으로 참조해도 자식 클래스에서 재정의한 메서드가 호출됨
new 키워드를 사용한 override : 키워드가 없는것과 같지만
명시적
이므로 컴파일러 경고가 발생하지 않음 ```cs namespace ConsoleApp1 { class parent { public virtual void func() { Console.WriteLine(“부모 클래스의 func”); } }
class child :parent
{
public override void func()
{
Console.WriteLine("자식 클래스의 func");
}
}
internal class Program
{
static void Main(string[] args)
{
List<parent> list = new List<parent>();
list.Add(new child() );
foreach(parent items in list)
{
items.func();
}
new child().func();
}
} } ```
하지만 부모 클래스에서 virtual 메서드로 정의한 메서드라도
자식 클래스에서 override 키워드를 사용해서 오버라이딩 하지 않으면
처음 처럼 부모 클래스의 메서드가 실행된다.
결국 상위클래스의 메서드를 우선 시 하고싶으면 그냥 오버라이딩하고
하위 클래스의 메서드를 우선 시 하고싶으면 virtual과 override 키워드를 사용해서 오버라이딩을 해야한다.
abstract 추상 클래스
직접적으로 인스턴스를 생성할 수 없는 클래스
상속을 위한 베이스 클래스로 사용 abstract 키워드를 사용하여 선언되고 abstract 키워드를 사용한 추상 메서드를 포함할 수 있다.
앞서한 virtual은 override 키워드의 유무에 따라서 어떤 클래스의 메서드를 따를지 정해줄 수 있었지만
abstarct는 반드시 override 키워드를 사용해서 구현
해야한다.