가상 함수(virtual function)는 파생 클래스에서 재정의 할 것으로 기대하는 멤버 함수를 의미한다. 파생 클래스에서 필요에 따라서 재정의(override) 할 수 있지만 필수적으로 재정의 할 필요는 없다. virtual 한정자를 사용한 클래스는 완벽한 기능을 제공할 수 있다. (구현부를 제공한다)
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("Nothing!");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("멍멍!");
}
}
Dog temp = new Dog();
temp.Speak();//멍멍!
사용 예시
파생 클래스에서 반드시 재정의해야 하는 멤버 함수를 의미한다. 이러한 추상 함수는 함수 본체(구현부)가 없고, 메서드 시그니처만 존재한다. 따라서 파생 클래스에서 재정의하지 않으면 사용할 수 없다.
하나 이상의 추상 함수(순수 가상 함수)를 포함하는 클래스를 추상클래스라고 한다. 즉, 반드시 사용되어야 하는 멤버함수를 추상클래스에 추상 함수로 선언해 놓으면, 이 클래스로부터 파생된 모든 클래스에서는 이 추상 함수를 반드시 재정의 해야한다.
public abstract class Animal
{
public abstract void Speak();
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("멍멍!");
}
}
Dog temp = new Dog();
Animal temp1 = new Animal(); // 컴파일에러
temp.Speak();//멍멍!
사용 예시
virtual 과 abstract
interface는 멤버 변수를 가지지 못하고 메소드, 이벤트, 인덱서, 프로퍼티만을 가질 수 있다. 인터페이스는 보통 여러 클래스에 공통적인 기능을 추가하기 위해 사용된다. 다중상속이 불가능한 C#에서 다중 구현이 가능하게 해준다.
public interface ISpeakable
{
void Speak();
}
public interface IEatable
{
void eat();
}
public interface IHitable
{
void hit();
}
public class Speaker : ISpeakable
{
public void Speak()
{
Console.WriteLine("노래재생");
}
}
public class Dog : ISpeakable, IEatable, IHitable
{
public void Speak()
{
Console.WriteLine("멍멍!");
}
public void Eat()
{
Console.WriteLine("호로록");
}
public void Hit()
{
Console.WriteLine("깨물기");
}
}
ISpeakable dog = new Dog();
dog.Speak(); // 출력: 멍멍!
사용 예시