본문 바로가기
전공/C# 프로그래밍

11강. 인터페이스와 추상 클래스 (1)

by 임 낭 만 2023. 5. 23.

인터페이스 (Interface)

인터페이스(Interface) 선언

  • 인터페이스는 interface 키워드를 이용해서 선언
  • 메소드, 이벤트, 인덱서, 프로퍼티만을 가질 수 있음
    • 메소드, 이벤트, 인덱서, 프로퍼티의 구현부는 없음
    • 접근 제한 한정자(e.g. private) 사용 불가
  • 인터페이스는 인스턴스를 만들 수 없음
    • 인터페이스를 상속받는 클래스의 인스턴스를 만드는 것은 가능

더보기

인터페이스는 청사진

  • 클래스 (a.k.a Concrete 클래스)는 객체의 청사진
  • 인터페이스는 클래스의 청사진
  • 클래스가 해야하는 행동결정 : 즉, 클래스가 어떤 메소드를 가질지 결정

[특징]

  • 가능한 멤버 : 메소드, 이벤트, 인덱서, 프로퍼티
  • 대개 interface의 I로 시작하는 이름으로 명
  • 구현부 없음
  • 모두 public으로 선언
  • 인스턴스 생성 불가 (참조는 가능)
  • 인터페이스를 상속 받은 클래스의 인스턴스 생성 가능

인터페이스 사용

  • 인터페이스를 상속받는 파생 클래스
    • 인터페이스에 선언된 모든 메소드(및 프로퍼티)를 구현 해야함
    • 해당 메소드들은 public 한정자로 수식
  • 인터페이스는 인스턴스를 만들 수 없지만 참조는 만들 수 있음
    • 참조에 파생 클래스 객체의 위치를 저장
using System;

namespace Interface
{
	//ILogger 인터페이스를 상속받는 파생 클래스
    interface ILogger { void WriteLog(string message); }
    class ConsoleLogger : ILogger
    {
        public void WriteLog(string msg)
        {
            Console.WriteLine("{0} {1}", DateTime.Now.ToLocalTime(), msg);
        }
    }
    class MainApp
    {
    	//인터페이스 참조에 파생클래스 객체의 위치 저장
        static void Main(string[] args)
        {
            ILogger logger = new ConsoleLogger();
            logger.WriteLog("Hello, World");
        }
    }
}

인터페이스는 약속이다

인터페이스를 상속하는 실체 클래스는 반드시 인터페이스에서 선언된 메소드를 모두 구현해야 함.

실체 클래스가 어떤 인터페이스의 파생 클래스인지를 알고 있다면 그 클래스가 어떤 public 메소드를 제공하는지도 파악할 수 있음

  • USB 포트를 예를 들어 설명하면, PC와 주변기기는 USB 포트라는 약속을 따름
    • USB 플래시 메모리를 꽂아 넣으면 저장 장치로 사용
    • 키보드나 마우스를 꽂으면 입력 장치로 사용
  • 인터페이스도 소프트웨어 내에서 USB와 같은 역할 수행
    • 클래스가 따라야 하는 약속
    • 인터페이스로부터 파생될 클래스가 어떤 메소드를 구현해야 할지를 정의
  • ILogger 인터페이스는 파생클래스에 WriteLog() 메소드 구현을 강제
    • ConsoleLogger 파생클래스를 선언하여 콘솔에 로그 출력하도록 WriteLog() 구현가능
    • 또한, ILogger를 상속받는 새로운 클래스를 선언하여 파일에 로그출력도 가능

ILogger 인터페이스 사용 예제

  • ClimateMonitor 클래스
    • 사용자로부터 온도를 반복적으로 입력 받아 기록
    • 로그를 저장하는 방식은 개발자의 결정에 따라 달라질 수 있도록 구현
  • ILogger 인터페이스를 상속 받는 ConsoleLogger 클래스
    • WriteLog() 메소드 구현 필수
    • 콘솔에 로그를 출력
using System;

namespace Interface1
{
    interface ILogger { void WriteLog(string message); }
    class ConsoleLogger : ILogger
    {
        public void WriteLog(string message)
        {
            Console.WriteLine("{0} {1}", DateTime.Now.ToLocalTime(), 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)
        {
		//ConsoleLogger 객체를 생성자에 인수로 넘김
            ClimateMonitor monitor = new ClimateMonitor(new ConsoleLogger());
            monitor.start();
        }
    }
}

  • ILogger 인터페이스를 상속 받는 FileLogger 클래스
    • WriteLog() 메소드 구현 필수
    • 파일에 로그를 출력
using System;

namespace Interface2
{
    interface ILogger { void WriteLog(string message); }
    class FileLogger : ILogger
    {
        private StreamWriter writer;
        public FileLogger(string path)
        {
            writer = File.CreateText(path);
            writer.AutoFlush = true;
        }
        public void WriteLog(string message)
        {
            Console.WriteLine("{0} {1}", DateTime.Now.ToLocalTime(), 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)
        {
            //FileLogger 객체를 생성자에 인수로 넘김
            ClimateMonitor monitor = new ClimateMonitor(new FileLogger("MyLog.txt"));
            monitor.start();
        }
    }
}

댓글