왜 인터페이스를 명시 적으로 구현해야합니까?
인터페이스를 명시 적으로 구현하기위한 올바른 사용 사례는 무엇입니까?
클래스를 사용하는 사람들이 인텔리전스의 모든 메소드 / 속성을 볼 필요가 있는지 확인하기입니까?
동일한 메소드와 다른 구현으로 두 개의 인터페이스를 구현하는 경우 명시 적으로 구현해야합니다.
public interface IDoItFast
{
void Go();
}
public interface IDoItSlow
{
void Go();
}
public class JustDoIt : IDoItFast, IDoItSlow
{
void IDoItFast.Go()
{
}
void IDoItSlow.Go()
{
}
}
선호하지 않는 멤버를 숨기는 것이 유용합니다. 예를 들어, 다 구현 둘 IComparable<T>
하고 IComparable
일반적으로 IComparable
사람들에게 다른 유형의 object-를 비교할 수 있다는 인상을주지 않기 위해 과부하를 숨기는 것이 좋습니다. 어떤 일부 인터페이스는 CLS와 호환 IConvertible
되지 인터페이스를 명시 적으로 구현하지 않습니다. CLS 준수가 필요한 언어 최종 사용자는 사용할 수 없습니다. (BCL 구현자가 프리미티브의 IConvertible 멤버를 숨기지.) 매우 비참한 것입니다.
또 다른 흥미로운 점은 일반적으로 사용되는 구성을 사용한다는 것 인터페이스를 명시 적으로 구현하는 인터페이스 유형에 대한 모든 구현을 통해서만 인터페이스를 호출 할 수 있다는 것을 의미합니다. 제약 조건을 사용하여 하여이 문제를 사용할 수 있습니다.
void SomeMethod<T>(T obj) where T:IConvertible
때 때 int를 상자에 넣지 언어.
인터페이스를 명시 적으로 구현해야하는 몇 가지 추가 이유 :
이전 버전과의 호환성 : ICloneable
인터페이스가 변경되는 경우 메소드 클래스 멤버를 구현할 때 메소드 서명을 변경할 필요가 없습니다.
더 높은 코드 : Clone
ICloneable에서 메소드를 제거 하면 컴파일러 오류가 발생 하지만 메소드를 사용하지 않고 '분리 된'공용 메소드로 끝날 수 있습니다.
강력한 타이핑 : 예제로 수퍼 캣의 이야기를 설명하기 위해, 이것은 내가 선호하는 샘플 코드이며, 인스턴스 멤버 로 직접 호출 할 때 ICloneable
명시 적으로 Clone()
입력 할 수 있습니다 MyObject
.
public class MyObject : ICloneable
{
public MyObject Clone()
{
// my cloning logic;
}
object ICloneable.Clone()
{
return this.Clone();
}
}
또 다른 유용한 기술은 함수의 공개 구현 메소드가 인터페이스에 지정된 것보다 더 구체적인 값을 리턴하는 것입니다.
예를 들어 반환은 구현할 ICloneable
수있는 메소드를 공개적으로 볼 수 Clone
있습니다.
에는 마찬가지로 을 반환하는 메서드 IAutomobileFactory
가있을 수 있지만 을 구현하는 에는 메서드가 (에서 파생 된 )를 반환 할 수 있습니다 . 그것은 그것이 있다는 것을 알고있는 것을 사용할 수 에 의해 반환 된 객체에-특정 속성을 배역으로하지 않고, 단지 그것이 어떤 종류의 것을 알고 코드를 코드하는 것 같은 그것의 반환 된 것을 다루는 것을 의미 합니다.Manufacture
Automobile
FordExplorerFactory
IAutomobileFactory
Manufacture
FordExplorer
Automobile
FordExplorerFactory
FordExplorer
FordExplorerFactory
IAutomobileFactory
Automobile
멤버 이름과 유용이 동일한 두 개의 인터페이스가 사용 방법에 따라 서명 동작을 변경하려는 경우에도합니다. (이와 같은 코드를 작성하지 않는 것이 좋습니다) :
interface Cat
{
string Name {get;}
}
interface Dog
{
string Name{get;}
}
public class Animal : Cat, Dog
{
string Cat.Name
{
get
{
return "Cat";
}
}
string Dog.Name
{
get
{
return "Dog";
}
}
}
static void Main(string[] args)
{
Animal animal = new Animal();
Cat cat = animal; //Note the use of the same instance of Animal. All we are doing is picking which interface implementation we want to use.
Dog dog = animal;
Console.WriteLine(cat.Name); //Prints Cat
Console.WriteLine(dog.Name); //Prints Dog
}
내부 인터페이스가 필요한 클래스의 멤버를 공개적으로 구현하지 않고 명시 적으로 구현해야합니다. 암시 적 구현은 공개되어야합니다.
공용 인터페이스를 깔끔하게 유지하여 인터페이스를 명시 적으로 구현할 수 있습니다. 즉, File
클래스가 IDisposable
명시 적으로 구현 Close()
하고 소비자에게 더 많은 공용 메소드 를 제공 할 수 있습니다 Dispose(
.
F # 은 명시 적 인터페이스 구현 만 제공하므로 해당 기능에 액세스하려면 항상 특정 인터페이스로 캐스팅해야하므로 인터페이스를 매우 명시 적으로 (말장난없이) 사용할 수 있습니다.
명시 적 구현의 또 다른 이유는 유지 관리 때문 입니다.
클래스가 "바쁜"상태가되었을 때 (예, 우리 모두가 다른 팀원의 코드를 리팩토링 할 수있는 사치가 없습니다.) 명시 적 구현을 통해 인터페이스 계약을 충족 할 수있는 메서드가 있음을 분명히 알 수 있습니다.
따라서 코드의 "가독성"이 향상됩니다.
System.Collections.Immutable
작성자가 컬렉션 유형에 대해 익숙한 API를 보존하는 동시에 새로운 유형에 대해 의미가없는 인터페이스 부분을 긁어 내기 위해이 기술을 사용하기로 선택한 다른 예가에서 제공됩니다 .
구체적 ImmutableList<T>
구현 IList<T>
및 이에 따른 ICollection<T>
( 순서는 있도록 ImmutableList<T>
하면서도, 기존의 코드와 함께 쉽게 사용할 수) void ICollection<T>.Add(T item)
대해 아무 의미 ImmutableList<T>
기존 목록을 변경해서는 안 불변의리스트에 요소를 추가 버젼 : ImmutableList<T>
또한 도출을으로부터 IImmutableList<T>
그 IImmutableList<T> Add(T item)
사용될 수있다 불변 목록.
따라서의 경우 Add
구현은 ImmutableList<T>
결국 다음과 같이 보입니다.
public ImmutableList<T> Add(T item)
{
// Create a new list with the added item
}
IImmutableList<T> IImmutableList<T>.Add(T value) => this.Add(value);
void ICollection<T>.Add(T item) => throw new NotSupportedException();
int IList.Add(object value) => throw new NotSupportedException();
명시 적으로 정의 된 인터페이스의 경우 모든 메소드는 자동으로 비공개이므로 액세스 수정자를 공개 할 수 없습니다. 다음을 가정하십시오.
interface Iphone{
void Money();
}
interface Ipen{
void Price();
}
class Demo : Iphone, Ipen{
void Iphone.Money(){ //it is private you can't give public
Console.WriteLine("You have no money");
}
void Ipen.Price(){ //it is private you can't give public
Console.WriteLine("You have to paid 3$");
}
}
// So you have to cast to call the method
class Program
{
static void Main(string[] args)
{
Demo d = new Demo();
Iphone i1 = (Iphone)d;
i1.Money();
((Ipen)i1).Price();
Console.ReadKey();
}
}
// You can't call methods by direct class object
이것이 우리가 Explicit Interface를 생성하는 방법입니다. 인터페이스 가 2 개이고 인터페이스가 동일한 메소드를 가지고 있고 단일 클래스가이 2 개의 인터페이스를 상속한다면, 하나의 인터페이스 메소드를 호출 할 때 컴파일러는 어떤 메소드를 호출할지 혼란스러워 할 수 있습니다. 명시 적 인터페이스를 사용하여이 문제를 관리합니다. 다음은 내가 아래에 준 한 가지 예입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace oops3
{
interface I5
{
void getdata();
}
interface I6
{
void getdata();
}
class MyClass:I5,I6
{
void I5.getdata()
{
Console.WriteLine("I5 getdata called");
}
void I6.getdata()
{
Console.WriteLine("I6 getdata called");
}
static void Main(string[] args)
{
MyClass obj = new MyClass();
((I5)obj).getdata();
Console.ReadLine();
}
}
}
참고 URL : https://stackoverflow.com/questions/4103300/why-implement-interface-explicitly
'IT' 카테고리의 다른 글
Azure Storage에 Blob이 있는지 확인 (0) | 2020.07.17 |
---|---|
어깨에서 ObjectiveC 구문 분석 정수 (0) | 2020.07.17 |
안드로이드 위치 클라이언트 -GPS 또는 네트워크는? (0) | 2020.07.17 |
서비스 경로없이 요청 URI를 얻는 방법은 무엇입니까? (0) | 2020.07.17 |
스칼라에서 사용할 JSON 라이브러리는 무엇입니까? (0) | 2020.07.17 |