추상 클래스와 인터페이스

추상클래스는 클래스를 설계할 때 어떠한 행위에 강요를 주는 문법이다.

 

예를들어 부모 클래스를 상속받는다면 무조건 특정 함수를 오버라이딩해야 하는 경우, 클래스에 abstract를 붙인다.

 

abstract class Monster
{
	public virtual void Shout() {}
}

class Orc : Monster
{
	
    public override void Shout()
    { // 구현 }
}

 

위 코드의 경우, Monster class를 상속받은 오크 클래스는 반드시 Shout() 함수를 구현해야 한다.

 

 

이렇게 추상클래스를 만들었으면, 이 Monster 클래스는 인스턴스를 만들지 못하고 추상적으로만 사용하는 개념이 된 것이다.

(new로 인스턴스 생성 시 오류)

 

 

 

 

 

추상 클래스 안에서는 함수도 추상적으로 만들 수 있다.

함수 앞의 virtual을 없애고 abstract를 붙이면 된다.

 

이것은 실제 내용이 해당 추상 함수에서는 존재하지 않는다는 의미이기 때문에,

추상클래스 본문 안에서는 선언하면 안된다. 이것 역시 개념적으로만 존재한다.

 

 

 

이렇게 추상함수를 만들게 되면

해당 추상함수가 있는 클래스를 상속받는 클래스들은 반드시 이 abstract로 선언된 함수를 꼭 override해야 한다.

 

결국 반드시 해당 함수를 사용하라는 인터페이스를 강요한 것이다.

 

 

 

 

상황에따라 강요를 여러개 하고싶을수도 있다.

그런데 c#은 다중상속이 안된다.

 

 

왜안되게했냐면

같은 추상클래스를 상속받은 클래스들은 같은 추상함수들을 오버라이드할텐데

그 함수들을 다중상속을 하게되면, 어떤 override된 함수를 불러와야 할지 애매해지기 때문이다.

 

 

그래서 c#에서는 문법상으로 다중상속을 허락하지 않는다.

그렇다면 위 예시같이 동일한 함수를 호출하지 않는 경우에도 다중 상속을 사용할 수 없게 된다.

 

 

 

같은 인터페이스로 만들어진, 같은 이름의 함수가 다른 구현부를 물려받았기 때문에 문제가 발생했던 것인데 

이런 상황을 해결하기 위해서

반대로, 인터페이스는 물려주지만 구현부는 네가 알아서 해라 라는 새로운 문법을 만들면

다중상속 문제를 어느정도 해결할수있다.

 

interface IFlyable
{
	void Fly();
}

class Orc : Monster, IFlyable // 인터페이스 강제
{
	public override void Shout(){} // Monster가 추상 클래스라 강제됨
}

 

나를 상속한다면 (나의 기능을 갖고 있다면),  반드시 이 인터페이스를 구현해야한다고 강제해줄 수 있다.

 

비록 다중상속은 안되지만, 인터페이스는 부모클래스의 상속과 더불어서 사용할 수 있다.

 

 

 

만약에 인터페이스를 활용하여 객체를 생성한다면 아래와 같이 사용할 수 있다.

static void DoFly(IFlyable flyable)
{
	flyable.Fly();
}

main()
{
	
    FlyableOrc orc = new FlyableOrc();
    DoFly(orc);
}