Chpt 14 인터페이스

Download Report

Transcript Chpt 14 인터페이스

Chpt 14







C#은 다중상속을 지원하지 않음
인터페이스라는 형태로 다중상속 비슷한 걸 제공함
타입들간의 표준적인 소통 방법

인터페이스 상속

타입 때문에 다중 구현이 힘든 기능들을 인터페이스로 제공함
클래스는 위에서 아래로만 상속가능
인터페이스는 그런거 없음
인터페이스를 상속한 클래스마다 다른 구현을 할 수 있음
인터페이스 VS 클래스?

클래스를 상속받는다고 하면


메소드를 통째로 상속받음
인터페이스를 상속받는다고 하면
메소드 이름과 시그니처만 받음
 구현은 해당 클래스에서 해야함



어떤 타입을 요구한다고 할 때 해당 클래스의 하위 클래스의 인스턴스
를 넘겨줄 수 있듯
해당 인터페이스 타입을 요구하는 모든 코드에 인터페이스를 상속하
는 클래스의 인스턴스를 넘겨줄 수 있음
메소드(인자)
{내용;}
클래스
메소드(인자)
{내용;}
(똑같은 내용)
(혹은 재정의)
메소드(인자);
인터페이스
메소드(인자)
{내용;}
(상속 클래
스가 구현)

메소드 이름과 시그니처만 모아놓은 집합




추상 클래스랑 비슷함
이벤트와 속성도 지정할 수 있음
생성자와 인스턴스 필드는 안됨
CLR은 정적 멤버도 가질 수 있도록 하지만
CLS는 허용안함
 물론 C#도 안함



Interface 키워드
관례상 이름 앞에 I를 붙임

인터페이스간에도 상속을 받을 수 있음
여러 개도 받을 수 있음
 인터페이스를 상속받는 인터페이스를 상속받는
클래스는
 줄줄이 엮인 모든 인터페이스들의 메소드를 구현해야 함
 사실 상속이라기 보다는 계약에 가까움

미사카는 미사카는


인터페이스 메소드는 public으로 선언해야 함(C# 컴파일러가 요구함)
인터페이스 메소드는 virtual로 선언해야 함(CLR이 요구함)
안 할 경우에는 상속 불가능한 메소드로 만들어버림
 상속받는 클래스에서 같은 인터페이스를 상속해서 독자적으로 구현하면 해결
 -???- MSDN에 의하면 기본 클래스가 인터페이스를 구현하는 경우 파생 클래스는 해
당 구현을 상속한다고 되어있는데요? (암시적으로 구현한다고 함)

▪

http://msdn.microsoft.com/ko-kr/library/ms173156(v=VS.100)
값 타입도 인터페이스 구현 가능

값 타입을 인터페이스 타입으로 변환할 경우 박싱해야 함
▪
인터페이스는 참조 타입이기 때문

타입이 CLR에 로드되면






타입의 메소드 테이블이 생기고 초기화됨
기본 타입인 Object 타입에 정의된 모든 인스턴스 메소드와
인터페이스를 상속하는 경우 인터페이스의 메소드와 실제 구현 메소드가 전부 올라
감
C# 컴파일러의 경우 타입이 구현한 메소드가 인터페이스의 메소드의 구현이라고 가
정함
둘을 같은 구현을 참조하도록 메타데이터를 구성함
명시적 인터페이스 구현






타입 내에 이미 동일한 이름의 메소드가 있는 경우
구현이 달라야 하는 경우 인터페이스 구현을 명시적으로 하면
뼈와 살이 분리됩니다
[InterfaceName].[MethodName]으로 선언
접근 제한자를 지정할 수 없음 (C# 컴파일러가 무조건 private을 붙여서 컴파일함)
재정의 불가

제네릭

타입 대리자
▪
대리자 T
인스턴스를 만들기 전까진 모르는 타입임
 주로 컬렉션 클래스를 만드는 데에 사용함
 System.Collections.Generic


인터페이스에게 타입 안정성을 강화하기 위해서

어떤 인터페이스는 Object 혹은 그 변환타입을 사용하는 메소드를 담고있을 수 있음
▪

인자의 타입에 따라서 인터페이스 메소드를 다르게 구현할 수도 있음


형 변환의 타입 안정성 문제가 발생할 수 있음
값 형식이 들어오면 굳이 박싱을 하지 않게도 할 수 있음
제네릭 인터페이스를 만드는데
매개변수가 특정 인터페이스를 반드시 상속(과 구현)을 하게 만들어야 한다면?
 인터페이스 제약을 두자


불필요한 박싱을 줄일 수 있음

IL이 값 타입을 인터페이스에 직접 넘겨버림


동일한 이름의 메소드를 정의한 여러 개의 인터페이스를 구현

명시적 인터페이스 구현으로 각 메소드를 호출하고 각 메소드를 따로 구현

박싱과 언박싱을 줄일 수 있음
특정 타입들에 대해서 다른 연산을 수행하게 할 수 있음
▪
▪
▪
▪
▪
▪
▪
▪
▪
▪
▪
▪
public interface IComparable{
Int32 CompareTo(Object other);
}
internal struct SomeValueType : IComparable{
private Int32 x;
public SomeValueType(Int32 n) {x = n;}
public Int32 CompareTo(SomeValueType other){
return (x – other.x);
Int32 IComparable.CompareTo(Object other){
return CompareTo((SomeValueType) other);
} // 접근 제한자가 없음에 주의할 것.
}



명시적 인터페이스를 선언하면 일어나는 일들을 알아야

잘 써먹을 수 있다

제네릭을 쓰면 도움이 된다

명확한 가이드라인이 없음
남발하지 않는 게 좋다
몇 가지 허점
▪
▪
▪
지금은 있어요(MSDN 검색하면 나옴)
기본 타입은 분명히 인터페이스 구현이 되어있다고 들었는데 실제로 메소드를 호출하면 없다고 나옴
기본타입을 인터페이스로 형 변환 해야 호출 가능
값 타입의 인스턴스는 인터페이스로 형 변환 할 때 박싱됨
 VS 인텔리센스 지원도 없음

▪
▪
▪

지금은 해요
역시 책이 구작
http://msdn.microsoft.com/ko-kr/library/tx1s9z1w(v=vs.80).aspx
파생된 타입에서 호출할 수 없음
▪
▪
상위 클래스에서 메소드 구현을 가상 메소드 형식으로 제공하고
하위 클래스에서 가상 메소드를 재정의함으로써 해결



제일 중요한거
딱히 정의된 건 없음
IS-A 관계와 CAN-DO 관계를 잘 파악해야함

관계가 계층적인가 혹은 수평적인가?
▪





전자는 클래스 후자는 인터페이스
사용의 편의성
구현의 일관성
버전 관리
Microsoft에서 만든 컬렉션들은 클래스랑 인터페이스를 둘 다 제공함

편한대로 쓰세요

사실 쓰는것도 어려움
쓰는거야 쉽지만 만드는건 어렵죠