안녕하세요.
결론적으로 말씀드려, 명시적 인터페이스 구현에서만 public 액세스 한정자를 사용할 수 없습니다. 모양의 차이만 보시면 됩니다. IDog.Eat() 이냐, 그냥 Eat()이냐, 인터페이스.메서드() 형태에는 public 접근 한정자를 제거합니다.
C#에서 인터페이스를 구현할 때 public 액세스 한정자의 사용에 대한 이해는 두 가지 주요 개념, 즉 명시적(Explicit)과 암시적(Implicit) 인터페이스 구현을 통해 이루어집니다.
1. 명시적 인터페이스 구현 (Explicit Interface Implementation)
예제 45.5에서, Pet 클래스는 IDog와 ICat 인터페이스를 명시적으로 구현합니다. 이 경우 IDog.Eat과 ICat.Eat 메서드는 서로 다른 구현을 가질 수 있습니다.
명시적 인터페이스 구현에서는 메서드에 public 액세스 한정자를 사용할 수 없습니다. 이는 해당 메서드들이 인터페이스 타입으로 캐스팅된 객체를 통해서만 접근 가능하기 때문입니다.
예를 들어, ((IDog)pet).Eat()를 통해 Pet 객체를 IDog 타입으로 캐스팅한 후 Eat 메서드를 호출할 수 있습니다.
2. 암시적 인터페이스 구현 (Implicit Interface Implementation)
예제 45.4에서, Dog 클래스는 IAnimal과 IDog 인터페이스를 암시적으로 구현합니다. 이 경우, Eat과 Yelp 메서드는 암시적으로 구현되어 있습니다.
암시적 구현에서 클래스 내의 메서드는 public으로 선언될 수 있으며, 이 메서드들은 클래스의 인스턴스를 통해 직접 호출될 수 있습니다.
예를 들면, dog.Eat()과 같이 Dog 클래스의 인스턴스를 통해 Eat 메서드를 직접 호출할 수 있습니다.
결국, 명시적 구현은 인터페이스 메서드들이 서로 충돌할 때 유용하게 사용될 수 있으며, 이때 public 액세스 한정자는 사용될 수 없습니다. 반면에, 암시적 구현은 더 일반적인 시나리오에서 사용되며 여기서는 public 액세스 한정자를 사용할 수 있습니다.
참고로, 제가 실제 업무용으로 쓰는 모든 애플리케이션에서는 명시적인 인터페이스 구현은 사용하고 있지 않습니다.
On 2023-11-21 오후 9:06:00, '홍수정' wrote:
안녕하세요, 강사님. 강사님의 책 C# 교과서의 예제를 풀다가 궁금한 부분이 있어 문의 드립니다.
제가 인터페이스의 설명을 보고 이해한 바로는 인터페이스를 상속받는 클래스는 인터페이스의 멤버가 반드시 구현되어야 하기 때문에 인터페이스 멤버에 쓸 수 없는 public 액세스 한정자 또한 상속받은 클래스에서도 사용할 수 없다고 이해했습니다.
그래서 45.5 명시적 인터페이스 구현 예제처럼 public 액세스 한정자를 쓰면 오류가 나야 한다고 생각했습니다.
45.5 명시적인 인터페이스 구현
namespace NotUnderstoodYet
{
interface IDog
{
void Eat();
}
interface ICat
{
void Eat();
}
class Pet : IDog, ICat
{
public void IDog.Eat() => WriteLine("Dog"); //오류 발생 (public 한정자가 유효하지 않음)
void ICat.Eat() => WriteLine("Cat");
}
class Print
{
static void Main(string[] args)
{
Pet pet = new Pet();
((IDog)pet).Eat();
}
}
}
그런데 45.4 다중 상속 예제나 다른 예제에서도 인터페이스를 상속받은 클래스에서 public 액세스 한정자를 쓰더라구요.. 제가 개념을 잘못 이해한 것 같은데 아무리 찾아도 정확한 답을 알 수 없어 문의 드립니다. 어떤 이유로 public 액세스 한정자를 사용해도 오류가 나지 않는 건가요? 두 예제 간의 차이가 뭘까요?
45. 4 인터페이스를 사용한 다중 상속 구하기
namespace InterfaceInheritance
{
interface IAnimal
{
void Eat();
}
interface IDog
{
void Yelp();
}
class Dog : IAnimal, IDog
{
public void Eat() => WriteLine("먹다."); //실행 잘됨...
public void Yelp() => WriteLine("짖다.");
}
class InterfaceInheritance
{
static void Main()
{
Dog dog = new Dog();
dog.Eat();
dog.Yelp();
}
}
}