인터페이스
구현 없이 메서드 선언만 포함된 클래스 문법과 유사하다.
추상메서드만 0개 이상 담고 있는 추상 클래스로 봐도 무방.
1 2 3 4 5 6 7 8 9 10 11 | abstract class DrawingObject { public abstract void Draw(); public abstract void Move(int offset); } interface IDrawingObject { void Draw(); void Move(); } |
추상클래스를 쓰면되지 왜 인터페이스를 만들었을까?
- 클래스는 다중 상속이 불가능 하기 때문.
1 2 3 4 | class Notebook : Computer, IMonitor, IKeyboard { void IMonitor.TurnOn(){}; // 추상메서드와 다르게 override 키워드가 } |
Computer 클래스, IMonitor 인터페이스, IKeyboard 인터페이스를 상속받음(IKeyboard는 빈 인터페이스)
* 인터페이스의 메서드를 자식클래스에서 구현할 때는 반드시 public 접근제한자를 명시해야 함.
public 이 없다고 해서 private이 되는건 아님.
1 2 3 4 5 6 | interface IMonitor { void TurnOn(); int Inch {get; set;} // 프로퍼티 포함 가능 int Width {get;} // get만도 가능 } |
인터페이스에 속한 메서드는 모두 가상메서드에 속한다. 따라서 virtual을 일부러지정하지 못하게 막음.
또한 자식클래스에서 override도 막음.
인터페이스의 메서드는 가상메서드기 때문에 다형성 특징이 나타남
* 인터페이스 자체는 new로 인스턴스화 불가하지만 인터페이스 배열은 만들 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Program { interface IDrawingObject { void Draw(); } class Line : IDrawingObject { public void Draw() { Console.WriteLine("Line"); } } class Rectangle : IDrawingObject { public void Draw() { Console.WriteLine("Rectangle"); } } static void Main(string[] args) { IDrawingObject[] instance = new IDrawingObject[] { new Line(), new Rectangle() }; foreach(IDrawingObject item in instance) { item.Draw(); // 상속받은 개체의 Draw메서드 호출 } } } | cs |
- 빈 인터페이스도 활용가능하다 예를들면 ToString메서드를 재정의한 클래스에다가 빈 인터페이스로 표시해서 효과를 누릴 수 있다.
인터페이스로도 콜백을 구현할 수 있다. (보통 인터페이스로 콜백을 많이 구현)
delegate는 메서드마다 정의해야하는 불편이 있지만 delegate 체인으로 한번에 여러메서드를 호출할 수 있는 장점이 있다.
느슨한 결합
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Computer { public void TurnOn() { Console.WriteLine("Computer : Turn ON"); } } class Switch { public void PowerOn(Computer machine) { machine.TurnOn(); } } |
위의 코드는 강한 결합의 코드다.
왜냐하면 Switch는 PowerOn을 할 때 항상 Computer클래스가 와야하기 때문에 두 클래스간의 결합이 강하다.
따라서 컴퓨터대신 모니터클래스로 변경할 때 Switch클래스도 바꿔야하는 큰 단점이 있다.
이것을 해결하는게 인터페이스를 통한 느슨한 결합이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | interface IPower { void TurnOn(); } class Monitor : IPower { public void TurnOn() { Console.WriteLine("Monitor : Turn ON"); } } class Switch { public void PowerOn(IPower machine) { machine.TurnOn(); } } |
이런식으로 처리하면 IPower를 상속받은 어떤 클래스가 와도 Switch의 변경없이 구현 가능하다.
'C#' 카테고리의 다른 글
C# event (0) | 2017.09.19 |
---|---|
C# 구조체, ref, out (6) | 2017.09.18 |
C# delegate (콜백, 체인, 범용성) (0) | 2017.09.16 |
C# 다형성 (override, overload, implicit, explicit) (0) | 2017.09.15 |
C# 캡슐화, 상속(접근제한자, 프로퍼티, as, is, Object, this, base) (0) | 2017.09.15 |