100 likes | 367 Views
Chpt 14. 인터페이스. overview. C# 은 다중상속을 지원하지 않음 인터페이스라는 형태로 다중상속 비슷한 걸 제공함 타입들간의 표준적인 소통 방법 인터페이스 상속 클래스는 위에서 아래로만 상속가능 인터페이스는 그런거 없음 인터페이스를 상속한 클래스마다 다른 구현을 할 수 있음 타입 때문에 다중 구현이 힘든 기능들을 인터페이스로 제공함 인터페이스 VS 클래스 ?. 클래스 상속 vs 인터페이스 상속. 클래스를 상속받는다고 하면 메소드를 통째로 상속받음 인터페이스를 상속받는다고 하면
E N D
Chpt 14 인터페이스
overview • C#은 다중상속을 지원하지 않음 • 인터페이스라는 형태로 다중상속 비슷한 걸 제공함 • 타입들간의 표준적인 소통 방법 • 인터페이스 상속 • 클래스는 위에서 아래로만 상속가능 • 인터페이스는 그런거 없음 • 인터페이스를 상속한 클래스마다 다른 구현을 할 수 있음 • 타입 때문에 다중 구현이 힘든 기능들을 인터페이스로 제공함 • 인터페이스 VS 클래스?
클래스 상속 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 structSomeValueType : 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 • 파생된 타입에서 호출할 수 없음 • 상위 클래스에서 메소드 구현을 가상 메소드 형식으로 제공하고 • 하위 클래스에서 가상 메소드를 재정의함으로써 해결
디자인 : 인터페이스 vs클래스 • 제일 중요한거 • 딱히 정의된 건 없음 • IS-A 관계와 CAN-DO 관계를 잘 파악해야함 • 관계가 계층적인가 혹은 수평적인가? • 전자는 클래스 후자는 인터페이스 • 사용의 편의성 • 구현의 일관성 • 버전 관리 • Microsoft에서 만든 컬렉션들은 클래스랑 인터페이스를 둘 다 제공함 • 편한대로 쓰세요 • 쓰는거야 쉽지만 만드는건 어렵죠 • 사실 쓰는것도 어려움