[c#] 인터페이스와 클래스의 차이점은 무엇이며 클래스에서 직접 메서드를 구현할 수 있는데 인터페이스를 사용해야하는 이유는 무엇입니까?

나는 이것이 매우 기본적인 질문이라는 것을 알고 있지만 면접관이 매우 속임수로 내게 물었고 나는 무력했습니다.

저는 인터페이스에 대한 물질적 또는 이론적 정의 만 알고 있으며 제가 작업 한 많은 프로젝트에서도 구현했습니다. 그러나 나는 이것이 왜 그리고 어떻게 유용한 지 이해하지 못합니다.

나는 또한 인터페이스에서 한 가지를 이해하지 못합니다. 예를 들어, 우리는

conn.Dispose();드디어 블록에서. 하지만 클래스가 IDisposable인터페이스 ( SqlConnection) 클래스를 구현하거나 상속하고 있다는 것을 알지 못합니다 . 메서드 이름을 어떻게 호출 할 수 있는지 궁금합니다. 또한 마찬가지로 Dispose 메서드가 작동하는 방식을 이해하지 못합니다. 모든 인터페이스 메서드에 대해 자체 구현으로 함수 본문을 구현해야하기 때문입니다. 그렇다면 인터페이스는 어떻게 수락되거나 계약으로 명명됩니까? 이 질문들은 지금까지 내 마음 속에 계속 떠 올랐고 솔직히 내가 이해할 수있는 방식으로 내 질문을 설명 할 좋은 스레드를 본 적이 없었습니다.

평소와 같이 MSDN은 매우 무섭게 보이며 한 줄도 명확하지 않습니다 ( 고급 개발에 참여하는 사람들, 친절하게도 변명합니다. 어떤 코드 나 기사도 그것을 보는 사람의 마음에 닿아 야한다고 강하게 느낍니다. 따라서 다른 많은 사람들이 말하는 것처럼 MSDN 사용하지 않습니다 ).

면접관은 다음과 같이 말했습니다.

그는 5 개의 메소드를 가지고 있으며 클래스에서 직접 구현하는 것을 기쁘게 생각합니다.하지만 Abstract 클래스 나 인터페이스로 가야한다면 어떤 것을 선택하고 그 이유는 무엇입니까? 나는 추상 클래스와 인터페이스의 장점과 단점을 여러 블로그에서 읽은 모든 것에 대답했지만 그는 확신하지 못하고 “Why Interface”를 일반적으로 이해하려고 노력하고있다. 일반적으로 동일한 메서드를 한 번만 구현할 수 있고 변경하지 않아도 “Why abstract class”.

인터넷에서 인터페이스와 그 기능에 대해 명확하게 설명하는 기사를 얻을 수 있습니다. 나는 여전히 인터페이스에 대해 모르지만 (나는 내가 사용한 이론과 방법을 알고있다) 그 많은 프로그래머 중 한 명이지만 내가 그것을 명확하게 이해했다는 것에 만족하지 않는다.



답변

인터페이스는 다음과 같은 것을 만들고 싶을 때 탁월합니다.

using System;

namespace MyInterfaceExample
{
    public interface IMyLogInterface
    {
        //I want to have a specific method that I'll use in MyLogClass
        void WriteLog();       
    }

    public class MyClass : IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyClass was Logged");
        }
    }

    public class MyOtherClass : IMyLogInterface
    {

        public void WriteLog()
        {
            Console.Write("MyOtherClass was Logged");
            Console.Write("And I Logged it different, than MyClass");
        }
    }

    public class MyLogClass
    {
        //I created a WriteLog method where I can pass as a parameter any object that implements IMyLogInterface.
        public static void WriteLog(IMyLogInterface myLogObject)
        {
            myLogObject.WriteLog(); //So I can use WriteLog here.
        }
    }

    public class MyMainClass
    {
        public void DoSomething()
        {
            MyClass aClass = new MyClass();
            MyOtherClass otherClass = new MyOtherClass();

            MyLogClass.WriteLog(aClass);//MyClass can log, and have his own implementation
            MyLogClass.WriteLog(otherClass); //As MyOtherClass also have his own implementation on how to log.
        }
    }
}

제 예에서 저는를 MyLogClass작성하는 개발자 일 수 있고 다른 개발자는 클래스를 생성 할 수 있으며 로깅을 원할 때 인터페이스를 구현할 수 있습니다 IMyLogInterface. WriteLog()에서 메소드 를 사용 하기 위해 구현해야하는 것이 무엇인지 묻는 것 입니다 MyLogClass. 인터페이스에서 찾을 수있는 답입니다.


답변

인터페이스를 사용하는 한 가지 이유는 코드의 유연성을 높이기 때문입니다. 다음과 같이 Account 클래스 유형의 객체를 매개 변수로 취하는 메소드가 있다고 가정 해 보겠습니다.

public void DoSomething(Account account) {
  // Do awesome stuff here.
}

이것의 문제는 메소드 매개 변수가 계정의 구현에 고정된다는 것입니다. 다른 유형의 계정이 필요하지 않은 경우 괜찮습니다. 대신 계정 인터페이스를 매개 변수로 사용하는이 예제를 사용하십시오.

public void DoSomething(IAccount account) {
  // Do awesome stuff here.
}

이 솔루션은 구현에 고정되어 있지 않습니다. 즉, SuperSavingsAccount 또는 ExclusiveAccount (둘 다 IAccount 인터페이스 구현)를 전달하고 구현 된 각 계정에 대해 다른 동작을 얻을 수 있습니다.


답변

인터페이스 는 구현자가 따라야하는 계약입니다. 추상 클래스 는 계약과 공유 구현을 허용합니다. 인터페이스는 가질 수 없습니다. 클래스는 여러 인터페이스를 구현하고 상속 할 수 있습니다. 클래스는 하나의 추상 클래스 만 확장 할 수 있습니다.

왜 인터페이스인가

  • 기본 또는 공유 코드 구현이 없습니다.
  • 데이터 계약 (웹 서비스, SOA)을 공유하려는 경우
  • 각 인터페이스의 구현에 대해 서로 다른 구현을 (가지고 IDbCommand있습니다 SqlCommandOracleCommand특정의 방법으로 인터페이스를 구현하는 )
  • 다중 상속지원 하려고합니다 .

왜 추상인가

  • 기본 또는 공유 코드 구현이 있습니다.
  • 코드 중복을 최소화하려는 경우
  • 버전 관리쉽게 지원 하고 싶습니다.

답변

여기에 이미지 설명 입력

따라서이 예제에서 PowerSocket은 다른 개체에 대해 아무것도 알지 못합니다. 개체는 모두 PowerSocket에서 제공하는 Power에 의존하므로 IPowerPlug를 구현하고 그렇게하여 연결할 수 있습니다.

인터페이스는 객체가 서로에 대해 알 필요없이 함께 작동하는 데 사용할 수있는 계약을 제공하기 때문에 유용합니다.


답변

한마디로- 다형성 때문에 !

“구현이 아닌 인터페이스로 프로그래밍”하면 동일한 인터페이스 (유형)를 공유하는 다른 객체를 메소드에 인자로 주입 할 수 있습니다. 이렇게하면 메서드 코드가 다른 클래스의 구현과 결합되지 않습니다. 즉, 동일한 인터페이스의 새로 생성 된 객체에 대해 작업 할 수 있도록 항상 열려 있습니다. (개폐 원칙)

  • Dependency Injection을 살펴보고 Design Patterns-Elements of Reusable Object-Oriented Software by GOF를 읽어보십시오 .

답변

C #에는 덕 타이핑이 없습니다. 특정 메서드가 구체적인 클래스 집합에 구현된다는 것을 알고 있다고해서 해당 메서드를 호출하는 것과 관련하여 모두 동일하게 처리 할 수 ​​있다는 의미는 아닙니다. 인터페이스를 구현하면 인터페이스가 정의하는 것과 관련하여 인터페이스를 구현하는 모든 클래스를 동일한 유형으로 처리 할 수 ​​있습니다.


답변

이 질문에 이미 많은 피가 흘렀다 고 생각하며, 많은 사람들은 일반인이 이해할 수없는 로봇과 같은 용어를 설명함으로써이 문제를 해결하려고합니다.

그래서 먼저. 인터페이스와 추상이 무엇인지 알아야하는 이유를 알 수 있습니다. 저는 팩토리 클래스를 신청할 때이 두 가지를 개인적으로 배웠습니다. 이 링크 에서 좋은 자습서를 찾습니다.

이제 내가 이미 준 링크를 기반으로 파헤쳐 보겠습니다.

사용자 요구 사항에 따라 변경 될 수있는 Vehicle 클래스가 있습니다 (예 : Truck , Tank , Airplane 등).

public class clsBike:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Bike");
    }
    #endregion
}

public class clsCar:IChoice
{
   #region IChoice Members
    public string Buy()
    {
       return ("You choose Car");
    }
    #endregion
}

둘 다 내 클래스에 Buy 메서드가 있어야한다고 말하는 Contract IChoice가 있습니다.

public interface IChoice
{
    string Buy();
}

이제 그 인터페이스는 메소드 만 적용 Buy()하고 상속 된 클래스가 구현할 때 수행 할 작업을 결정하도록합니다. 이것은 인터페이스의 한계입니다. 순수하게 인터페이스를 사용하면 abstact를 사용하여 자동으로 구현할 수있는 일부 작업을 반복 할 수 있습니다. 예를 들어 각 차량을 구매하면 할인이 적용됩니다.

public abstract class Choice
{
    public abstract string Discount { get; }
    public abstract string Type { get; }
    public string Buy()
    {
       return "You buy" + Type + " with " + Discount;
}
public class clsBike: Choice
{
    public abstract string Discount { get { return "10% Discount Off"; } }
    public abstract string Type { get { return "Bike"; } }
}

public class clsCar:Choice
{
    public abstract string Discount { get { return " $15K Less"; } }
    public abstract string Type { get { return "Car"; } }
}

이제 Factory Class를 사용하면 동일한 결과를 얻을 수 있지만 abstract를 사용하면 기본 클래스가 Buy()메서드를 실행하게합니다 .

요약 : 인터페이스 계약은 상속 클래스가 구현을 수행하도록하는 반면 추상 클래스 계약은 구현을 초기화 할 수 있습니다 (상속 클래스로 재정의 할 수 있음).