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


117

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

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

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

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

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

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

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

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


4
인터페이스도 이해하기 힘들었습니다. 좋은 질문.
Brian

4
구체적인 구현이 아닌 추상 계약으로 프로그래밍하는 것 .... 간단히 말해 인터페이스가 필요할 때 인터페이스를 구현하는 모든 객체를 대체 할 수 있습니다.
Mitch Wheat

7
SqlConnection상속 System.ComponentModel.Component되는 구현 IDisposable.
Lee

2
@MitchWheat - 그것은 예를 들어 될 운명이 아니에요, 문제는 방법을 묻는 SqlConnection구현을 IDisposable.
Lee

오, 이해 해주셔서 감사합니다. 하지만 여전히 "Dispose"메서드 기능이 정의 된 방법과 위치를 알 수 없습니다.
학습자

답변:


92

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

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. 인터페이스에서 찾을 수있는 답입니다.


3
안녕하세요 아주 좋은 성분과 같은 모습이 나를 이해하는 것을 정말 많이 :) 덕분에 그것을 감사
학습자

14
내 질문은 인스턴스화 MyClass하고 MyOtherClass왜 단순히 aClass.WriteLog()추가 단계를 추가 하지 않는지입니다 . 의 구현은 WriteLog()각 클래스마다 다르지만 이미 객체가 있으므로 핸들러 클래스에 전달하는 이유는 무엇입니까?
Zach M.

흠 당신의 로깅 예제를 너깃에 넣으면 다른 사람들이 세부 사항을 모르고 당신의 로거를 사용하는 것이 더 간단 할 수 있습니다. 로깅 및 알레르기 수준이있는 인터페이스) 인터페이스는 여전히 범위 내에 있습니다. 그래서 누가 그것으로부터 혜택을 받고 있는지 자신 외에?.
user3800527

2
@ZachM. 내가 맞다면 대답은 그가 클래스를 인스턴스화하지 않을 것이지만 다른 개발자는 클래스를 인스턴스화하고 매개 변수로 MyLogClass WriteLog메서드에 전달한다는 것을 의미 합니다. 따라서 그의 메서드는 IMyLogInterface. 여기 또 다른 흥미로운 게시물이 있습니다.
shaijut

1
내 질문은 왜 인터페이스입니까 ??? 위의 시나리오는 모든 추상 메서드가있는 추상 클래스로도 달성 할 수 있습니다.
Abhijit Ojha

52

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

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

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

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

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


45

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

왜 인터페이스인가

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

왜 추상인가

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

2
@Silver 나는 당신이 블로그에 타자 한 대부분의 것을 읽었지만, 나는 실질적으로 이해하려고 노력하고있다. WCF 서비스, 노출 된 인터페이스를 수행했습니다 (하지만 업스트림 또는 다운 스트림이없는 단일 독립 실행 형 앱). 따라서 인터페이스를 잘 설계하고 구현했지만 제대로 이해할 수 없었습니다. 내 질문은 실제로 계약이 의미하는 방법 이름을 공유하는 것입니다. 이게 어떻게 유용합니까? (나는 모든 방법을 강제로 구현해야한다는 것을 알고 있지만, 그렇지 않으면 어떻게해야합니까? 위의 인터페이스에 대한 게시물에서 두 번째 점은 공유라고 말합니다. 실제 실시간 예제를 제공 할 수 있음을 의미합니다.
Learner

1
인터페이스 및 SOA와 관련된 실제 예를 들어 , .NET 어셈블리 ( 예 : Contracts.Shared.dll ) 에서 WCF 인터페이스 ( DataContracts)를 공유 하여 .NET 클라이언트 소비자가 ( 서비스 참조 추가를 통한 코드 생성 방지 등)을 사용하여 쉽게 상호 운용 할 수 있도록합니다 . ) 또는 사용하여 공유 유형으로 서비스 참조 추가ChannelFactory
SliverNinja - MSFT

추상 calss 안에 추상 메서드 만 선언하면 추상 클래스가 인터페이스 역할을하는데 인터페이스가 필요한 이유는 무엇입니까?
Abhijit Ojha

25

여기에 이미지 설명 입력

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

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


이것은 의미가 있지만 여전히 이해하기 어렵습니다 .PowerSocket에 대한 기본 클래스를 만들지 않고 필요한 경우 다른 모든 것들이 상속받을 수 있습니까? 기술적으로 전원 소켓은 다른 클래스에 대해 전혀 모릅니다.
altaaf.hussein

C #에서는 다중 상속이 허용되지 않기 때문에 생각합니다
Hugh Seagraves

22

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

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

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

4

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


3
동적 유형을 사용하여 .net4에서 일종의 덕 타이핑을 얻을 수 있습니다.
Tony Hopkinson 2012

4

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

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

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

사용자 요구 사항에 따라 변경 될 수있는 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()메서드를 실행하게합니다 .

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


2

인터페이스를 사용하여 다음을 수행 할 수 있습니다.

1) 구현의 다른 부분을 제공하는 분리 된 인터페이스를 생성하여보다 일관된 인터페이스를 허용합니다.

2) 인터페이스간에 이름이 같은 여러 메서드를 허용합니다. 구현이 충돌하지 않고 서명 만 있기 때문입니다.

3) 구현과 독립적으로 인터페이스를 버전 화하고 하이브하여 계약이 충족되도록 할 수 있습니다.

4) 코드는 구체화보다는 추상화에 의존 할 수 있으므로 테스트 모의 주입 등 스마트 종속성 주입이 가능합니다.

내가 확신하는 더 많은 이유가 있습니다.

추상 클래스를 사용하면 작업 할 부분적으로 구체적인 기반을 가질 수 있습니다. 이것은 인터페이스와 동일하지 않지만 템플릿 메서드 패턴을 사용하여 부분 구현을 만드는 기능과 같은 고유 한 특성을 가지고 있습니다.


가장 중요한 것은 무시했습니다. 인터페이스를 구현하면 해당 코드가 클래스에 대해 알 필요없이 해당 인터페이스의 구현이 필요한 모든 코드에서 클래스를 사용할 수있게됩니다.
supercat 2014-04-16

2

@ user2211290 답변의 실제 샘플 :

모두의 ArrayList인터페이스를 가지고 IList. 아래에는 a string[]와 a가 List<string>있으며 IList 를 사용하여 하나의 방법으로 둘 다 확인합니다 .

string[] col1 = { "zero", "one", "two", "three", "four"};
List<string> col2 = new List<string>{ "zero", "one", "two", "three"};

//a methode that manipulates both of our collections with IList
static void CheckForDigit(IList collection, string digit)
{
    Console.Write(collection.Contains(digit));
    Console.Write("----");
    Console.WriteLine(collection.ToString()); //writes the type of collection
}

static void Main()
{
    CheckForDigit(col1, "one");   //True----System.String[]
    CheckForDigit(col2, "one");   //True----System.Collections.Generic.List`1[System.String]



//Another test:

    CheckForDigit(col1, "four");   //True----System.String[]
    CheckForDigit(col2, "four");   //false----System.Collections.Generic.List`1[System.String]
}

1

하나의 추상 클래스에서만 상속 할 수 있습니다. 여러 인터페이스에서 상속 할 수 있습니다. 이것은 내가 대부분의 경우에 사용하는 것을 결정합니다.

추상 클래스의 장점은 기본 구현을 가질 수 있다는 것입니다. 그러나 IDisposable의 경우 기본 클래스가 제대로 정리하는 방법을 모르기 때문에 기본 구현은 쓸모가 없습니다. 따라서 인터페이스가 더 적합합니다.


1

추상 클래스와 인터페이스는 모두 계약입니다.

계약의 개념은 몇 가지 동작을 지정하는 것입니다. 구현했다고 말하면 계약에 동의 한 것입니다.

인터페이스보다 추상적 인 선택이 있습니다.

추상 클래스의 비추 상 자손은 계약을 구현합니다.

인터페이스를 구현하는 모든 클래스는 계약을 구현합니다.

따라서 모든 하위 항목이 별도의 인터페이스를 정의하여 구현하고 저장해야하는 일부 동작을 지정하려면 abstract를 사용하지만 이제 효과적으로 집계 된 계약을 충족하는 모든 항목은 하위 항목이어야합니다.


1

인터페이스는 현실 (객체)의 추상화 (클래스)의 추상화 (원형)를 만드는 것입니다.

인터페이스는 클래스에서 제공하는 구현을 제공하지 않고 계약 조건을 지정하는 것입니다.

인터페이스는 사양입니다.

  • 인터페이스는 개념의 움직이지 않는 동작을 지정하기위한 디자인 타임 아티팩트입니다.

  • 클래스는 상호 작용하고 이동할 때 현실의 모바일 구조를 지정하기위한 구현 시간 아티팩트입니다.

인터페이스 란?

고양이를 관찰하면 네 발, 머리, 몸통, 꼬리, 머리카락을 가진 동물이라고 말할 수 있습니다. 그가 걷고, 달리고, 먹고, 야옹 할 수 있음을 알 수 있습니다. 등등.

속성 및 작업으로 인터페이스를 정의했습니다. 따라서 작업 방식을 정의하지 않았고 작동 방식을 알지 못한 상태에서 기능과 기능 만 정의했습니다. 능력과 구별을 정의했습니다.

따라서 UML에서는 아티팩트에 대한 심층적 인보기를 시작하기 위해 개인 및 보호 된 구성원을 정의 할 수 있기 때문에이를 클래스 다이어그램에서 클래스라고 부르지 만 실제로 아직 클래스가 아닙니다. UML에서 인터페이스는 C #의 인터페이스와 약간 다르므로 여기서 혼동하지 마십시오. 추상화 원자에 대한 부분 액세스 포인트와 같습니다. 따라서 우리는 클래스가 여러 인터페이스를 구현할 수 있다고 말했습니다. 따라서 C #의 인터페이스는 추상화를 추상화하고이 추상화를 액세스 포인트로 제한하는 데 모두 사용되기 때문에 동일하지만 그렇지 않습니다. 두 가지 용도가 있습니다. 따라서 UML의 클래스는 프로그래밍 클래스에 대한 완전한 결합 인터페이스를 나타내는 반면 UML 인터페이스는 프로그래밍 클래스 섹션의 분리 인터페이스를 나타냅니다. 과연, UML의 클래스 다이어그램은 구현을 처리하지 않으며 모든 아티팩트는 프로그래밍 인터페이스 레벨에 있습니다. UML 클래스를 프로그래밍 클래스에 매핑하는 동안 이는 추상 추상화를 구체적인 추상화로 바꾸는 것입니다. 디자인 분야와 프로그래밍 분야 사이의 이분법을 설명하는 미묘함이 있습니다. 따라서 UML의 클래스는 내부 숨겨진 것을 고려하면서 프로그래밍 인터페이스의 관점에서 프로그래밍 클래스입니다.

인터페이스는 또한 어색한 방식으로 사용할 수없는 경우 다중 상속을 시뮬레이션 할 수 있습니다. 예를 들어, cat 클래스는 동물 인터페이스에서 파생되는 cat 인터페이스를 구현합니다. 이 고양이 클래스는 또한 걷기, 달리기, 먹고 소리 내기 등의 인터페이스를 구현합니다. 이것은 클래스 수준에서 다중 상속의 부재를 보상하지만 모든 것을 다시 구현해야 할 때마다 현실 자체가하는 것처럼 현실을 고려할 수 없습니다.

인터페이스 및 구현 섹션을 단위로 정의하는 Pascal Object 코딩을 참조 할 수 있음을 이해하기 위해. 인터페이스에서 유형을 정의하고 구현에서 유형을 구현합니다.

unit UnitName;

interface

type
  TheClass = class
  public
    procedure TheMethod;
  end;

implementation

class procedure TheClass.TheMethod;
begin
end;

여기서 인터페이스 섹션은 UML 클래스 디자인과 일치하지만 인터페이스 유형은 다른 것입니다.

그래서 우리 사업에서 우리는 별개이지만 유사한 두 가지를 지명하기위한 하나의 단어 인 interface를 가지고 있으며 이는 혼란의 근원입니다.

또한 예를 들어 C #에서 프로그래밍 인터페이스는 강력한 형식의 hability를 잃었 기 때문에 목표를 실제로 성공하지 않고도 개방형 형식에 대한 진정한 제네릭 다형성의 부재를 보상 할 수 있습니다.

결국, (분산) 공통 개체 모델에서 소개 된 것처럼 메모리에서 개체의 구현 및 관리에 대한 걱정없이 호환되지 않는 시스템이 통신 할 수 있도록 인터페이스가 필요합니다.

수업이란?

외부 관점에서 현실의 축소를 정의한 후 내부 관점에서 설명 할 수 있습니다.이 클래스는 캡슐화 된 현실이 실현되고 감사가 상호 작용할 수 있도록 데이터 처리 및 메시지 관리를 정의하는 클래스입니다. 인스턴스를 사용하는 개체에.

따라서 UML에서는 기계의 바퀴에 프랙탈 몰입을 실현하고 처리하려는 현실 조각의 추상화를 구현할 수 있도록 상태, 상호 작용 등을 설명합니다.

따라서 추상 클래스는 컴파일러의 관점에서 보면 인터페이스와 동일합니다.

추가 정보

프로토콜 (객체 지향 프로그래밍)

C #-인터페이스

C #-클래스


1

비행 토스터에 대해 말씀 드리겠습니다.

비행 토스터

물론 인터페이스를 선언하거나 구현하지 않고도 작동하는 소프트웨어 시스템을 구축 할 수있는 상황이 많이 있습니다. 모든 객체 지향 소프트웨어 디자인은 클래스 만 사용하여 실현할 수 있습니다.

그런 다음 모든 소프트웨어 시스템은 어셈블리 언어 또는 기계 코드로 구현할 수 있습니다. 추상화 메커니즘을 사용하는 이유는 작업을 더 쉽게 만드는 경향이 있기 때문입니다. 인터페이스는 그러한 추상화 메커니즘입니다.

따라서 인터페이스를 사용하면 구현하기가 훨씬 더 쉬운 사소하지 않은 객체 지향 디자인이 있으며 이러한 경우 인터페이스가 실제로 필요합니다.

이러한 사소하지 않은 디자인은 다중 상속과 관련이 있습니다. "진정한"형태는 클래스가 하나의 기본 클래스가 아니라 둘 이상의 기본 클래스에서 상속되는 경우입니다. 이 진정한 형태는 C #에서는 불가능하지만 C # 및 Java와 같은 언어가 등장하기 전에 지배적 인 언어는 진정한 다중 상속을 완벽하게 지원하는 C ++였습니다. 불행히도 진정한 다중 상속은 언어의 디자인을 엄청나게 복잡하게 만들고 유명한 "다이아몬드 문제"와 같은 다양한 문제를 일으키기 때문에 좋은 생각이 아니 었습니다. ( "다중 상속의 정확한 문제는 무엇입니까?"J Francis의 답변 참조)

따라서 누군가 "비행 토스터"클래스를 구축하려는 경우 기존 "토스터"클래스와 기존 "비행"클래스에서 상속합니다. 그들이 부딪 칠 수있는 문제의 종류는 토스터 클래스의 전원 공급 장치가 벽면 소켓 일 가능성이있는 반면, 비행 기계 클래스의 전원 공급 장치는 비둘기 음식 일 가능성이 높았으며 그 결과 새로운 클래스가 어떻게 든 둘 다 가지고 있거나 어떤 것이 있는지 불분명합니다. (다이아몬드 문제.)

C # 및 Java와 같은 언어의 제작자는 언어를 단순하게 유지하고 Diamond Problem과 같은 함정을 피하기 위해 진정한 다중 상속을 허용하지 않기로 결정했습니다. 그러나 어떤 형태의 다중 상속이 여전히 필요합니다. (또는 적어도 매우 바람직하기 때문에) 이러한 언어에서 그들은 진정한 다중 상속의 문제와 복잡성을 피하면서 더 적은 형태의 다중 상속을 지원하는 수단으로 인터페이스를 도입했습니다.

이보다 적은 형태의 다중 상속에서는 둘 이상의 기본 클래스에서 상속하는 클래스를 가질 수 없지만 적어도 하나 이상의 인터페이스에서 상속 할 수 있습니다. 따라서 플라잉 토스터를 빌드하려는 경우 기존 토스터 클래스와 기존 플라잉 클래스 모두에서 상속 할 수는 없지만 기존 토스터 클래스에서 상속 한 다음 직접 구현하는 플라잉 인터페이스를 노출하면됩니다. 토스터에서 이미 물려받은 수단을 사용합니다.

따라서 서로 다르고 관련이없는 두 가지 기능 집합을 집계하는 클래스를 만들 필요가 없다고 느끼지 않는 한, 어떤 형태의 다중 상속도 필요하지 않으므로 인터페이스를 선언하거나 구현할 필요가 없습니다.


0

인터페이스를 통해 클래스 디자이너는 최종 사용자에게 사용 가능한 메서드를 매우 명확하게 만들 수 있습니다. 그들은 또한 다형성의 필수적인 부분입니다.


첫 번째 진술에서 잘 말했습니다. 하지만 두 번째 진술을 이해하지 못했습니다. 실시간 예제로 자세히 설명해 주시겠습니까?
학습자

0

나는 당신이 이론을 아주 잘 알고 있다고 생각하고 SOLID 원칙을 알고 있다고 가정하므로 추상 클래스에 대한 인터페이스의 정의를 게시하지 않을 것입니다.

아시다시피 인터페이스는 코드를 가질 수 없으므로 단점은 이해하기가 매우 쉽습니다.

생성자를 제공하는 클래스의 속성을 초기화해야하거나 구현의 일부를 제공하려는 경우 추상 클래스가이를 허용하지 않는 인터페이스에 적합합니다.

따라서 일반적으로 클래스를 상속 / 확장 할 클라이언트에 생성자 또는 코드를 제공해야 할 때 인터페이스보다 추상 클래스를 선호해야합니다.


-2

추상 클래스는 관련 엔터티에 대해 생성되며 관련 엔터티에 인터페이스를 사용할 수 있습니다.

예를 들어, Animal과 Human이라는 두 개의 엔티티가 있으면 Interface로 이동하여 Tiger, lion이라고 자세히 말하고 Animal과 관련이 있고 Animal Abstract 클래스를 선택합니다.

아래와 같이 보일 것입니다

   Interface             
   ____|____
  |        |
Animal   Human



  Animal (Abstract class)
   __|___
  |      |
Tiger   Lion
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.