강의 목표

| 인터페이스는 청사진

클래스 = 객체의 청사진
인터페이스 = 클래스의 청사진
객체는 클래스를 사용해서 만들고, 클래스는 인터페이스를 사용하여 만든다

| 인터페이스는

클래스가 해야하는 메소드 결정


| 인터페이스 선언하기

interface로 선언
대부분 인터페이스 식별자(이름)은 ‘I’ 대문자르 사용하여 이름을 짓는다
인터페이스에 선언되는 메소드는 구현을 갖지 않는다
인터페이스는 필드도 갖지 않는다
인터페이스는 인터페이스를 상속하는 클래스의 메서드 목록을 결정한다
메소드 선언할 때 접근한정자 명시하지 않아도된다
하지만 상속하는 클래스에서는 public으로 선언해줘야함

interface ILogger
{
  void WriteLog(string log); 이게 끝임!! { } 이렇게 하는 구현이 없음
}


| 인터페이스는 약속이다

인터페이스를 상속하는 실체 클래스는 반드시 인터페이스에서 선언된 메소드를 모두 구현해야한다
실체클래스가 어떤 인터페이스의 파생클래스 인지 알고있으면 어떤 메소드를 구현하는지 미리알 수 있다.

interace ILogger{
  void WriteLog(string log);
}
class ConsoleLogger : ILogger{
  public void WriteLog(string message){
    Console.WriteLine("{0},{1}", DateTime.Now.ToLocalTime(),message)
  }
}
ILogger logger = new ConsoleLogger();  ILogger 형태이지?
logger.WriteLog("hello")

컴파일러의 생각
ILogger라는 인터페이스는 WriteLog라는 메소드를 가지고 있네
ConsoleLogger라는 클래스를 선언했네 얘는 ILogger를 상속했네
ConsoleLogger에 WriteLog라는 메소드 있나?
반환형, 이름, 매개변수목록이 모두 일치하는 것을 확인
있으면 컴파일 진행 없으면 컴파일 에러 발생


| 인터페이스는 커넥터 :star:

커넥터는 두 부품을 연결하는 중간 부품

interace ILogger{
  void WriteLog(string log);
}
class ClimateMonitor{
  private ILogger logger; // ILogger 참조를 필드로 가지고 있음
  public ClimateMonitor(ILogger logger) // 이 참조를 생성자를 통해 초기화를 하고있다
  {
    this.logger = logger;
  }
}

FileLogger와 CLimateMonitor 아무 상관이없음
그런데 ClimateMonitor 객체를 생산하는데 FileLogger 생성자를 호출함
ClimateMonitor의 생성자는 ILogger를 매개변수로 받는데 이게 가능한 이유?
자식 클래스는 부모클래스로 간주한다 했기 때문에 가능하다
=> 상속을 통해 커넥트 역할을 하기도한다

var monitor = new ClimateMonitor(new FileLogger("log.txt"))
class FileLogger : ILogger // 상속하고 있음
{ 
  private StreamWriter writer;
  public FileLogger(string path)
  {
    writer = File.CreateText(path);
    writer.AutoFlush - true;
  }
  public void WriteLog(string message) // ILogger에서 선언한 WriteLog 메소드를 구현하고 있고
  {
    writer.WriteLine(message);
  }
}




| 추상 클래스 : 인터페이스와 클래스 사이

인터페이스와 클래스 어딘가에 있는 녀석
추상클래스의 메서드는 구현을 가질 수 있다
하지만 객체를 생성할 수 없다!! (인터페이스와 공통점)
추상 메소드 :

인터페이스를 제공하되 자식 클래스가 구현해야할 메소드의 기본적인 구현을 함께 제공하고싶을때 사용

| 추상클래스 선언하기

abstract class 로 선언 추상메서드 이름 앞에는 abstract 한정자 써줘야함

abstract class 클래스 이름
{
  abstract 추상메소드이름(); //추상메서드

   메소드 이름
  {
    구현
  }
}