본문 바로가기

C# 공부/C# 기본 문법

인터페이스 (선언과 사용법, 상속, 다중상속)

A. 인터페이스(interface)의 선언과 사용법

선언시 메소드 구현부가 없으며, 접근제한 한정자를 사용할 수 없고, 모든것이 public으로 선언된다.

또한, 인터페이스는 인스턴스도 만들 수 없다.

하지만, 상속받는 클래스의 인스턴스를 만드는것은 가능하며, 이때 조건으로는 인터페이스에 선언되어있는 모든 메소드( 및 프로퍼티)를 구현해줘야하며, 이 메소드들은 public 한정자로 수식해야한다.

* 인터페이스 작명법은 인터페이스의 이름앞에 'I'를 붙이는것이 관례

interface ILogger //ConsoleLogger, FileLogger클래스는 ILogger를 상속하며, WriteLog() 메소드를 구현
{
	void WriteLog(string log);
}

class ConsoleLogger : ILogger 
{
    public void WriteLog(string message)
    {
    	Console.WriteLine("{0} {1}",DateTime.Now.ToLocalTime(), message);
    }
}

class FileLogger : ILogger
{
	private StreamWriter writer;
    
    public FileLogger(string path)
    {
    	writer = File.CreateText(path);
        writer.AutoFlush = true;
    }
    public void WriteLog(string message)
    {
    	writer.WriteLine("{0} {1}",DateTime.Now.ToShortTimeString(),message);
    }
}

class ClimateMonitor
{	
	private ILogger logger;
    public ClimateMonitor(ILogger logger)
    {
    	this.logger = logger;
    }
    
    public void start()
    {
    	while(true)
        {	
        	Console.Write("온도를 입력하세요 : ");
            string temperature = Console.ReadLine();\
            if(temperature =="")
            	break;
                
            logger.WriteLog("현재 온도 : "+temperature);
        }
    }
}

class MainAPP
{
	static void main(String[] args)
	{
        ClimateMonitor monitor = new ClimateMonitor(new FileLogger("MyLog.txt"));
        //여기서 ILogger logger=new FileLogger("MyLog.txt")가 가능한이유는 FileLogger가 ILogger에서 상속받았기때문이다.
        monitor.start();
	}
}

 

B. 인터페이스를 상속하는 인터페이스

인터페이스를 상속받는것은 클래스 뿐만 아니라 인터페이스도 가능하다.

기존 인터페이스를 수정할 수 없으며, 기존 인터페이스에 새로운 기능을 추가한 인터페이스를 만들고싶을때 사용한다.

케이스 1 - 상속하려는 인터페이스가 소스코드가 아닌 어셈블리로만 제공되는경우.

.NET Framework SDK에서 제공하는 인터페이스들의 그 예시. 

케이스 2 - 상속하려는 인터페이스의 소스코드를 갖고 있어도 이미 인터페이스를 상속하는 클래스들이 존재하는 경우

이런 상황에서 기존의 소스코드에 영향을 주지않고 새로운 기능을 추가하기 위해서는 인터페이스를 상속하는 인터페이스를 사용하는것이 좋다.

interface ILogger
{
	void WriteLog(string message);
}

interface IFormattableLogger : ILogger
{
	void WriteLog(string format, params Object[] args); //WriteLog 오버로딩 메소드 2가지를 가진다.
}

 

C. 여러개의 인터페이스 한번에 상속하기

C#에서 클래스는 프로그램의 모호함을 방지하기 위하여 클래스의 다중상속을 허용하지 않는다. ("죽음의 다이아몬드 문제")

하지만, 인터페이스는 내용이 아닌 외형을 물려주기때문에, 죽음의 다이아몬드같은 문제 발생하지않음.

interface IRunnable
{
    void Run();
}
interface IFlyable
{
    void Fly();
}
class FlyingCar : IRunnable, IFlyable
{
    public void Run()
    {
        Console.WriteLine("Run!");
    }
    public void Fly()
    {
        Console.WriteLine("Fly!");
    }
}

class Program
{
    static void Main(string[] args)
    {
        FlyingCar car = new FlyingCar();
        car.Run();
        car.Fly();

        IRunnable runnable = car as IRunnable;//FlyingCar이 IRunnable에서 상속받앗으므로 가능하다.
        runnable.Run();

        IFlyable flyable = car as IFlyable; //FlyingCar이 IFlyable에서 상속받앗으므로 가능하다.
        flyable.Fly();

        car.Run(); //위에서 car을 as로 형변환을 했어도 car객체의 형식은 FlyingCar로 똑같다. "Run!" 출력
        car.Fly(); //동일, "Fly!" 출력
    }
}