인터페이스 대 추상 클래스 (일반 OO)


1413

최근에 인터페이스와 추상 클래스의 차이점에 대해 두 번의 전화 인터뷰가있었습니다. 나는 내가 생각할 수있는 모든 측면을 설명했지만 특정 내용을 언급하기를 기다리고있는 것 같으며 그것이 무엇인지 모르겠습니다.

내 경험으로는 다음과 같은 것이 사실이라고 생각합니다. 중요한 점이없는 경우 알려주십시오.

상호 작용:

인터페이스에 선언 된 모든 단일 메소드는 서브 클래스에서 구현되어야합니다. 인터페이스에는 이벤트, 대리자, 속성 (C #) 및 메서드 만 존재할 수 있습니다. 클래스는 여러 인터페이스를 구현할 수 있습니다.

추상 클래스 :

서브 클래스는 추상 메소드 만 구현해야합니다. Abstract 클래스는 구현과 함께 일반적인 메소드를 가질 수 있습니다. 추상 클래스는 이벤트, 대리자, 속성 및 메서드 옆에 클래스 변수를 가질 수도 있습니다. C #에서 다중 상속이 존재하지 않기 때문에 클래스는 하나의 추상 클래스 만 구현할 수 있습니다.

  1. 그 후, 면접관은 "추상적 인 방법으로 만 추상 클래스가 있다면 어떻게 될까요? 인터페이스와 어떻게 다릅니 까?"라는 질문을 내놓았습니다. 나는 대답을 몰랐지만 위에서 언급 한 상속이라고 생각합니까?

  2. 다른 면접관이 인터페이스 내부에 공용 변수가 있는지 여부를 물었습니다. 추상 클래스와는 어떻게 다릅니 까? 인터페이스 안에 공용 변수를 가질 수 없다고 주장했습니다. 나는 그가 듣고 싶은 것이 무엇인지 몰랐지만 만족하지 못했습니다.

참조 :


412
두 사람의 차이점을 아는 것이 중요하다고 생각하지만 이것은 좋은 인터뷰 질문이 아닙니다. 직업이 OO 주제에 관한 책을 쓰고 있지 않는 한. 그 딩 박쥐를 위해 일하지 않는 것이 좋습니다.
Alan

107
@Alan : 나는 이것을 인터뷰 질문으로 실제로 좋아하지만 누군가에 대해 이런 식으로 방해하지는 않을 것입니다. "계층 구조를 정의 할 때 추상 기본 클래스에 대한 인터페이스를 어디에서 선택 하시겠습니까? "또는 이와 유사한 것입니다.
Reed Copsey

11
어쩌면 그들은 디자인에 중점을 둔 답변을 받았을 것입니다 ... 당신처럼 나는 그것을 기술적 인 질문으로 취급했을 것입니다.
CurtainDog


30
@Kave : I insisted you can't have a public variable inside an interface.인터페이스에 공용 변수가있을 수 있다고 생각합니다. 실제로 인터페이스의 변수는 자동으로 공개 및 최종 변수입니다.
학습자

답변:


746

귀하의 질문에 "일반 OO"에 대한 것이지만 실제로 이러한 용어의 .NET 사용에 초점을 맞추고있는 것 같습니다.

.NET (Java와 유사)에서 :

  • 인터페이스는 상태 또는 구현을 가질 수 없습니다
  • 인터페이스를 구현하는 클래스는 해당 인터페이스의 모든 메소드의 구현을 제공해야합니다.
  • 추상 클래스는 상태 (데이터 멤버) 및 / 또는 구현 (메소드)을 포함 할 수 있습니다.
  • 추상 클래스는 추상 메소드를 구현하지 않고 상속 될 수 있습니다 (이 파생 클래스는 추상 자체 임)
  • 인터페이스는 다중 상속 될 수 있으며 추상 클래스는 그렇지 않을 수 있습니다 (이것은 인터페이스가 abtract 클래스와 별도로 존재하는 주요한 구체적인 이유 일 수 있습니다. 일반 MI의 많은 문제를 제거하는 다중 상속 구현을 허용합니다).

일반적인 OO 용어로서 차이점을 반드시 명확하게 정의 할 필요는 없습니다. 예를 들어, 유사한 엄격한 정의를 보유 할 수있는 C ++ 프로그래머가 있습니다 (인터페이스는 구현을 포함 할 수없는 추상 클래스의 엄격한 서브 세트입니다). 일부는 기본 구현을 가진 추상 클래스가 여전히 인터페이스이거나 추상적이지 않다고 말할 수 있습니다. 클래스는 여전히 인터페이스를 정의 할 수 있습니다.

실제로, 공개 메소드가 개인 가상 메소드에 '고정'되는 비가 상 메소드 인 NVI (Non-Virtual Interface)라는 C ++ 관용구가 있습니다.


7
감사합니다. 귀하의 답변에 상태 + 모든 휴식에 대한 좋은 개요가 언급되어 있으므로 귀하의 답변을 최종 답변으로 표시합니다. 첫 번째 면접관이 일반 OO를 요청한 이후 일반 OO를 요청했지만 맞습니다. 그러나 C # 담당자이므로 잊어 버리는 경향이 있습니다. ;-) 또한 항상 ++가 마음을 불어 넣는 것처럼 C ++ 설명에 감사드립니다.
Houman

6
나는 마이클이 제공하는 설명의 핵심 포인트가 인터페이스를 구현할 때 인터페이스의 모든 멤버를 구현해야한다는 것입니다 생각하지만, 추상 클래스를 상속 할 때 그것은 부모의 멤버를 구현하는 하위 클래스에 의해 필요하지 않은 것
여보 고메즈

82
+1 : 인터뷰를 주최하는 원숭이가 다른 언어가 OO를 다르게 구현한다는 사실조차 깨닫지 못할 것입니다.
궤도에서 가벼움 경주

2
@ JL 문제가 어디에 있는지 알 수 없습니다. 추상 메소드와 추상 클래스를 혼동 한 것 같습니다. 추상 메소드 에는 구현이 없습니다. 그러나 abstract 클래스 내 에서 일부 메소드는 추상 (즉 구현하지 않음) 일 수 있지만 다른 메소드는 실제로 구현할 수 있습니다.
xji

19
Java 8에서는 인터페이스에 기본 메소드 및 정적 메소드를 가질 수 있으며 이는 Java 인터페이스가 구현 될 수 있음을 의미합니다. 여기를 참조 하십시오 . 분명히 당신은 주로 .NET을 언급했기 때문에 이것은 Java를 언급하는 관찰 일뿐입니다.
davtom

866

공군에있을 때 나는 조종사 훈련을 받고 USAF (미국 공군) 조종사가되었습니다. 그 시점에서 나는 아무것도 날 수 없었으며 항공기 유형 훈련에 참석해야했습니다. 자격을 갖추면 파일럿 (Abstract 클래스)과 C-141 파일럿 (콘크리트 클래스)이었습니다. 제 임무 중 하나에서 추가 책임이있었습니다 : 안전 책임자. 이제 나는 여전히 조종사 였고 C-141 조종사 였지만 안전 책임자 임무도 수행했습니다 (ISafetyOfficer를 구현했습니다). 조종사는 안전 요원 일 필요가 없었으며 다른 사람들도 그렇게 할 수있었습니다.

모든 USAF 조종사는 공군 전체의 특정 규정을 준수해야하며 모든 C-141 (또는 F-16 또는 T-38) 조종사는 'USAF 조종사'입니다. 누구나 안전 책임자가 될 수 있습니다. 요약하면 다음과 같습니다.

  • 파일럿 : 추상 클래스
  • C-141 파일럿 : 콘크리트 클래스
  • ISafety Officer : 인터페이스

덧붙여 참고 : 이것은 코딩 권장 사항이 아니라 개념을 설명하는 데 도움이되는 비유였습니다. 아래의 다양한 의견을 참조하십시오. 토론은 흥미 롭습니다.


87
저는이 비유를 정말 좋아합니다. 간단한 예제를 사용하여 약간 복잡한 주제를 설명합니다
Kevin Bowersox

13
이것은 복잡한 OO 용어를 이해하는 가장 좋은 방법입니다. 한마디로 모든 이론은 실제로 활용할 수있을 때만 가치가 있습니다. @Jay 당신은 예를 들어 몇 가지 총알 포인트를 파악하기가 정말 쉽습니다 (주로 흡수되는 대신 관통하는 마음!)
vs

54
나는 아직도 약간 혼란 스럽다. 예, 이제 F-16 및 T-38 자격을 갖추 Jay었 으므로 이제 클래스 는 여러 클래스 (C-141 파일럿, F-16 파일럿 및 T-38 파일럿)에서 상속 할 수 없습니다. 이는 누구의 클래스가 인터페이스가되어야합니까? 감사합니다
Alex Okrushko

37
많은 사람들이 Alex의 의견에 +1을 부여했습니다.이 예에서는 약간의 약점이 나타납니다. 먼저 Jay는 자체 클래스가 아닌 C-141Pilot의 인스턴스가 될 것이라고 말했습니다. 또한 USAF에서는 모든 조종사 중 99 %가 한 번에 한 항공기에서만 자격을 갖기 때문에 (FCF 및 테스트 조종사는 주목할만한 예외 임) 여러 자격을 고려하지 않았으며 구현 방법을 고려하지 않았습니다. 50 년 전 25 대의 다른 항공기에 동시에 자격을 갖춘 조종사에 대해 알고 있듯이, 다중 상속을 사용하고 싶지 않은 방법을 보여주는 것 같습니다.
Jay

20
한 명의 조종사가 한 번에 두 대 이상의 비행기를 비행 할 가능성이 없기 때문에 전략 패턴을 구현할 수있는 좋은 기회가 될 것입니다. 파일럿은 인증 모음을 보유하고 런타임시 올바른 인증을 선택합니다. 인증은 TakeOff, Land, Eject 메서드를 사용하여 IFlyPlane 인터페이스를 구현하는 동작으로 코딩됩니다.
Michael Blackburn

221

그들이 찾고있는 답은 근본적 또는 OPPS 철학적 차이라고 생각합니다.

추상 클래스 상속은 파생 클래스가 추상 클래스의 핵심 속성과 동작을 공유 할 때 사용됩니다. 실제로 클래스를 정의하는 행동의 종류.

반면에 인터페이스 상속은 클래스가 주변 클래스 동작을 공유 할 때 사용되며, 반드시 파생 클래스를 정의 할 필요는 없습니다.

예를 들어. 자동차와 트럭은 자동차 추상 클래스의 많은 핵심 속성과 동작을 공유하지만, Driller 또는 PowerGenerators와 같은 비 자동차 클래스도 공유하고 반드시 자동차 또는 트럭을 정의하지는 않지만 배기 생성과 같은 주변 동작을 공유합니다. 따라서 Car, Truck, Driller 및 PowerGenerator는 모두 동일한 인터페이스 IExhaust를 공유 할 수 있습니다.


32
더 나은 유추는 인터페이스 의 계약 특성을 보여주는 "usesFuel"이라고 생각합니다 .
Pureferret

@Pureferret accelerate자동차 추상 클래스의 핵심 행동의 일부 라면 계약 성격을 accelerate보여줄 수 없습니다 . 계약 성격이란 무엇입니까? 왜 우리가 이야기 할 때 마다이 단어가 소개 되었습니까? contractinterface
overexchange '11

일반적으로 인터페이스이기 때문에 @overexchange 단지 곳이 '표면'을 충족하지만, 단어 계약의 계약이 의미 하는 방법 두 '표면'대회가. 배기 가스를 발생시키는 것이 '동의한다'는 것은 (적어도 나에게는) 이해가되지 않습니다. 그러나 연료를 사용해야한다는 데 동의 할 수 있다는 것이 합리적입니다.
Pureferret

1
@Pureferret 나는 같은 링크에 대한 쿼리를 제기
overexchange

1
@Pureferret interface말초 행동이 필요한 경우 왜 public interface List<E> extends Collection<E> {}핵심 동작을 설명하도록 설계 list되었습니까? 이것은 실제로 prasun의 대답과 모순됩니다. 모두 Collection<E>List<E>인터페이스는 여기에 있습니다.
overexchange

198

요약 : 추상 클래스는 유사한 클래스의 클래스 계층 모델링 에 사용됩니다 (예 : 동물은 추상 클래스 일 수 있으며 Human, Lion, Tiger는 구체적인 파생 클래스 일 수 있음)

인터페이스는 클래스를 구현하는 클래스의 유형에 신경 쓰지 않는 2 개의 유사 / 비 유사 클래스 간의 통신에 사용됩니다 (예 : 높이는 인터페이스 속성 일 수 있으며 Human, Building, Tree로 구현 될 수 있습니다. 먹을 수 있는지 여부는 중요하지 않습니다) , 당신은 당신이 죽거나 무엇이든 수영 할 수 있습니다 .. 그것은 당신이 신장 (당신의 수업에서 구현)이 필요한 것만 중요합니다).


7
구조 보다는 인터페이스와 순수한 추상 클래스가 거의 동일하기 때문에 intent 와 같은 더 추상적 인 것을보고 사물 사이의 차이점이 다르기 때문에 때로는이 대답을 좋아합니다. 의회).
LostSalad

추상 클래스와 인터페이스가 특정 언어로 무엇을 할 수 있는지 열거하는 것은 쉽지만 객체에 의미와 책임을 부여하기 위해 추상화를 만드는 것이 더 어렵고, OO에서 2 개념의 사용을 완전히 재개하기는 어렵습니다. 감사!
사무엘

2
@ dhananjay : 동물 클래스의 개념에서 높이를 분리하고 다른 클래스에서 나올 수있는 방법을 알지만 클래스 간의 "통신"은 정확히 무엇을 의미합니까? 그것은 단지 자신의 클래스에 대해 높이를 정의하는 것입니다. 맞습니까?
TTT

77

몇 가지 다른 차이점이 있습니다.

인터페이스는 구체적으로 구현할 수 없습니다. 추상 기본 클래스가 가능합니다. 이를 통해 구체적인 구현을 제공 할 수 있습니다. 이를 통해 추상 기본 클래스가 실제로보다 엄격한 계약을 제공 할 수 있지만 인터페이스는 실제로 클래스 사용 방법 만 설명합니다. (추상 기본 클래스에는 비가 상 멤버가 동작을 정의하여 기본 클래스 작성자에게 더 많은 제어 권한을 부여 할 수 있습니다.)

클래스에서 둘 이상의 인터페이스를 구현할 수 있습니다. 클래스는 단일 추상 기본 클래스에서만 파생 될 수 있습니다. 인터페이스를 사용하는 다형성 계층 구조를 허용하지만 추상 기본 클래스는 허용하지 않습니다. 또한 인터페이스를 사용하는 의사 다중 상속이 가능합니다.

API를 중단하지 않고 v2 +에서 추상 기본 클래스를 수정할 수 있습니다. 인터페이스 변경으로 인해 변경이 발생했습니다.

[C # /. NET 특정] 추상 기본 클래스와 달리 인터페이스는 값 유형 (구조체)에 적용될 수 있습니다. 구조체는 추상 기본 클래스에서 상속 할 수 없습니다. 이를 통해 행동 계약 / 사용 지침을 가치 유형에 적용 할 수 있습니다.


5
클래스에서 둘 이상의 인터페이스를 구현할 수 있다는 핵심 요점은 +1입니다.
cgp

이것이 추상 기본 클래스 인 IMO에 비해 인터페이스에 대한 실질적인 이점 중 하나입니다. 그렇지 않으면 .NET 디자인 지침에 동의합니다. 이제는 "인터페이스보다 추상 기본 클래스를 선호합니다"
Reed Copsey

그러나 인터페이스가 모든 클래스에 적용될 수 있다는 점을 추가 할 수 있다면 예리합니다.
cgp

1
@altCognito : 두 번째 단락에서 처리 된 것으로 보입니다. 그러나 인터페이스가 값 유형에서 작동한다는 것을 상기시켜주었습니다.
리드 경찰

이 정확한 설명에 감사드립니다. 실제로 매우 도움이됩니다. 나 여기 처음이야. 두 개의 답변을 "답변"으로 선택할 수없는 것은 유감입니다. 나를 혼란스럽게하는 한 가지는 Abstract 'base'클래스의 사용법입니다. 모든 추상 클래스는 서브 클래스의 기본 클래스입니다. 왜 '베이스'를 추가로 명명합니까?
Houman

68

상속
자동차와 버스를 고려하십시오. 그들은 두 개의 다른 차량입니다. 그러나 여전히 스티어링, 브레이크, 기어, 엔진 등의 공통 속성을 공유
합니다. 상속 개념을 사용하면 다음과 같이 나타낼 수 있습니다.

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

이제 자전거 ...

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

그리고 자동차 ...

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

이것이 전부 상속 에 관한 것 입니다. 우리는 위에서 본 것처럼 객체를 더 간단한 기본 형식과 그 자식으로 분류하는 데 사용합니다.

추상 클래스

추상 클래스는 불완전한 객체입니다. 그것을 더 이해하기 위해 차량 비유를 다시 한번 생각해 봅시다.
차량을 운전할 수 있습니다. 권리? 그러나 다른 차량은 다른 방식으로 운전됩니다 ... 예를 들어 자전거를 운전하는 것처럼 자동차를 운전할 수 없습니다.
그렇다면 차량의 주행 기능을 나타내는 방법은 무엇입니까? 차량의 종류를 확인하고 자체 기능으로 운전하는 것이 더 어렵습니다. 새로운 유형의 차량을 추가 할 때 Driver 클래스를 반복해서 변경해야합니다.
다음은 추상 클래스와 메소드의 역할입니다. 상속하는 모든 자식이이 함수를 구현해야 함을 나타 내기 위해 drive 메서드를 abstract로 정의 할 수 있습니다.
차량 클래스를 수정하면 ...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

자전거와 자동차는 또한 운전 방법을 지정해야합니다. 그렇지 않으면 코드가 컴파일되지 않고 오류가 발생합니다.
간단히 말해서. 추상 클래스는 일부 불완전한 함수를 가진 부분적으로 불완전한 클래스이며 상속되는 자식은 자체적으로 지정해야합니다.

인터페이스 인터페이스가 완전히 불완전합니다. 속성이 없습니다. 그들은 상속받은 아이들이 무언가를 할 수 있음을 나타냅니다 ...
당신이 다른 유형의 휴대 전화를 가지고 있다고 가정하십시오. 그들 각각은 다른 기능을 수행하는 다른 방법을 가지고 있습니다. 예 : 사람에게 전화하십시오. 휴대 전화 제조업체가 수행 방법을 지정합니다. 여기서 휴대폰은 전화를 걸 수 있습니다. 즉, 전화를 걸 수 있습니다. 이것을 인터페이스로 표현해 봅시다.

public interface Dialable {
    public void dial(Number n);
}

여기서 다이얼 러블 제조업체는 번호를 다이얼하는 방법을 정의합니다. 당신은 전화 번호를 제공해야합니다.

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

따라서 추상 클래스 대신 인터페이스를 사용하면 Dialable을 사용하는 함수 작성기는 속성에 대해 걱정할 필요가 없습니다. 예 : 터치 스크린 또는 다이얼 패드가 있습니까? 유선 전화 또는 휴대폰입니까? 전화 걸기 가능 여부 만 알면됩니다. Dialable 인터페이스를 상속 (또는 구현)합니까?

더 중요한 것은 언젠가 다이얼 러블을 다른 것으로 바꾸면

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

다이얼 러블을 사용하는 기능이 다이얼 러블 인터페이스에 지정된 것 이외의 세부 사항에 의존하지 않으며 또한 불가능하기 때문에 코드가 여전히 완벽하게 작동하는지 확인할 수 있습니다. 둘 다 Dialable 인터페이스를 구현하며 이것이 기능에 관심을 갖는 유일한 것입니다.

인터페이스는 공통 기능을 공유하는 한 객체간에 상호 운용성을 보장하기 위해 개발자가 일반적으로 사용합니다 (전화 번호로 전화를 걸어야하는 한 유선 또는 휴대폰으로 변경할 수있는 것처럼). 요컨대, 인터페이스는 속성이없는 훨씬 단순한 버전의 추상 클래스입니다.
또한 원하는만큼 인터페이스를 구현 (상속) 할 수 있지만 단일 상위 클래스 만 확장 (상속) 할 수 있습니다.

더 많은 정보 추상 클래스와 인터페이스


"인터페이스에 속성이 없음"은 사실이 아닙니다.
Bigeyes

@Bigeyes, java는 인터페이스의 속성을 허용하지 않습니다. 다른 언어에서도 마찬가지라고 생각했습니다. 더 설명해 주시겠습니까?
fz_salam 2016 년

C # /. Net을 참조하고 있습니다. 예를
Bigeyes

인터페이스가 속성을 가질 수있는 C #의 @Bigeyes는 다중 상속 문제를 다시 소개하지 않습니까? 클래스가 동일한 속성을 정의한 여러 인터페이스를 사용하면 어떻게됩니까? 그냥 궁금해서 감사
stackPusher

@happycoder : re : "여기 추상 클래스 대신 인터페이스를 사용하면 속성에 대해 걱정할 필요가 없습니다. 예 : 터치 스크린 또는 다이얼 패드가 있습니까, 유선 전화 또는 휴대폰입니까? 다이얼 가능 여부를 알고 다이얼 가능 인터페이스를 상속 (또는 구현)합니까? " -코드 예제에서 이것을 보여줄 수 있고, 어떻게 상속되는지 보지 못했습니다 ...
TTT

45

java이 질문에 대답하기 위해 OOP 언어로 간주 하면 Java 8 릴리스에서는 위의 답변 중 일부 내용이 더 이상 사용되지 않습니다. 이제 자바 인터페이스는 구체적인 구현으로 기본 메소드를 가질 수 있습니다.

Oracle 웹 사이트 는 클래스 interfaceabstract클래스의 주요 차이점을 제공합니다 .

다음과 같은 경우 추상 클래스 사용을 고려하십시오 .

  1. 밀접하게 관련된 여러 클래스간에 코드를 공유하려고합니다.
  2. 추상 클래스를 확장하는 클래스에는 많은 공통 메소드 또는 필드가 있거나 public 이외의 액세스 수정 자 (예 : 보호 및 개인)가 필요합니다.
  3. 비 정적 또는 최종이 아닌 필드를 선언하려고합니다.

다음과 같은 경우 인터페이스 사용을 고려하십시오 .

  1. 관련없는 클래스가 인터페이스를 구현할 것으로 기대합니다. 예를 들어, 많은 관련이없는 객체가 Serializable인터페이스 를 구현할 수 있습니다.
  2. 특정 데이터 유형의 동작을 지정하려고하지만 누가 그 동작을 구현하는지는 신경 쓰지 않습니다.
  3. 여러 유형의 상속을 활용하려고합니다.

간단히 말해서 사용하고 싶습니다

인터페이스 : 여러 관련없는 객체로 계약을 구현하려면

추상 클래스 : 여러 관련 개체간에 동일하거나 다른 동작을 구현하려면

명확한 방법으로 사물을 이해하기 위해 코드 예제를 살펴보십시오 . 인터페이스와 추상 클래스의 차이점을 어떻게 설명해야합니까?


33

면접관들은 이상한 나무를 짖고 있습니다. C # 및 Java와 같은 언어에는 차이가 있지만 C ++과 같은 다른 언어에는 차이가 없습니다. OO 이론은 두 언어를 구별하는 것이 아니라 언어의 구문을 구별합니다.

추상 클래스는 상속 될 구현과 인터페이스 (순수 가상 메소드)를 모두 갖춘 클래스입니다. 인터페이스에는 일반적으로 구현이없고 순수한 가상 함수 만 있습니다.

C # 또는 Java에서 구현이없는 추상 클래스는 상속하는 데 사용되는 구문과 인터페이스에서만 상속 할 수있는 구문에서만 인터페이스와 다릅니다.


일주일 전에 같은 질문을 받았는데 Java에 대한 경험이 없지만 지금은 C ++로 작업하고 있습니다. 면접관은 질문하기 전에 언어를 지정하지 않았으므로이 경우 인터페이스는 상태 나 구현이없는 추상 클래스라고 설명했습니다. 나는 그것이 또한 이상한 질문이라는 것에 동의합니다.
dacabdi

31

인터페이스를 구현하면 상속 ( "is-a"관계) 대신 구성 ( "has-a"관계)이 달성됩니다. 그것은 상속 대신에 행동의 구성을 달성하기 위해 인터페이스를 사용해야하는 디자인 패턴과 같은 것들에 관해서 기억해야 할 중요한 원리입니다.


17
인터페이스는 IMO와 같은 "Acts-as-a"관계를 더 많이 달성합니다. 캡슐화는 인터페이스보다 구성을 향상시킵니다.
Reed Copsey

12
인터페이스 구현이 구성 될 것이라고 생각하지 않습니다.
Pavan Dittakavi

또한 인터페이스는 IDisposable과 같은 "기능"을 설명하는 데 더 많이 사용됩니다. 예전에는 이러한 클래스가 무엇인가 할 수있는 클래스간에 기능을 공유했습니다. IFlyable의 더 많은 예는 조류와 비행기로 구현할 수 있습니다. 그러나 Bird는 airecraft가 AirCraft에서 파생 된 Class Creature에서 파생 될 수 있습니다.
Peter.Wang

26

인터페이스와 추상 클래스의 깊이 세부 사항을 설명합니다. 인터페이스와 추상 클래스에 대한 개요를 알고 있다면 먼저 인터페이스를 사용해야 할 때와 추상 클래스를 사용해야 할 때 먼저 질문을 떠 올립니다. 아래 인터페이스 및 추상 클래스에 대한 설명을 확인하십시오.

  1. 언제 인터페이스를 사용해야합니까?

    구현에 대해 모른다면 요구 사항 사양이 있고 인터페이스를 사용합니다.

  2. 우리는 언제 추상 클래스를 사용해야합니까?

    구현을 알고 있지만 완전히 (일부 구현은 아님) 추상 클래스를 사용합니다.

    상호 작용

    기본적으로 모든 공개 추상 방법은 인터페이스가 100 % 순수 추상임을 의미합니다.

    요약

    Abstract 클래스에 구현이있는 Concrete 메소드 및 Abstract 메소드를 가질 수 있습니다. Abstract 클래스는 abstract로 선언 된 클래스입니다. 추상 메소드를 포함하거나 포함하지 않을 수 있습니다.

    상호 작용

    인터페이스를 개인용으로 선언 할 수 없습니다

    Q. 인터페이스를 개인용으로 보호하고 선언하지 않은 이유는 무엇입니까?

    기본적으로 인터페이스 메소드는 public abstract이므로 인터페이스를 개인용 및 보호 형으로 선언하지 않는 이유가 있습니다.

    인터페이스 방법
    은 또한 개인, 보호, 최종, 정적, 동기화, 기본으로 인터페이스를 선언 할 수 없습니다 .....

    이유는 다음과 같습니다. 인터페이스의 객체를 생성 할 수 없어 동기화 된 메소드를 선언하지 않는 이유와 동기화는 객체에 대한 작업이므로 동기화 된 메소드를 선언하지 않는 이유 일시적인 개념은 동기화 된 임시 작업으로 인해 적용 할 수 없습니다.

    요약

    우리는 public, private final static ..와 함께 행복하게 사용하고 있습니다. 추상적으로 제한이 적용되지 않음을 의미합니다.

    상호 작용

    변수는 기본적으로 public static final로 인터페이스에 선언되므로 변수를 개인용으로 보호하지도 않습니다.

    인터페이스 변수는 기본적으로 공개 정적 최종 및 최종 변수이므로 휘발성 수정 자도 인터페이스에 적용 할 수 없습니다. 값을 변수에 할당 한 후에는 값을 변경할 수 없으며 변수를 인터페이스에 선언 한 후에는 변수를 할당해야합니다.

    휘발성 변수는 변경 사항을 유지하므로 opp입니다. 마지막으로 인터페이스에서 휘발성 변수를 사용하지 않는 이유입니다.

    요약

    추상 변수는 공개 정적 최종을 선언 할 필요가 없습니다.

이 기사가 도움이 되길 바랍니다.


4
이 점에 동의하지 않습니다 Abstract class must have at lease one abstract method.. 구현하는 한 Abstract 메서드없이 Abstract 클래스를 가질 수 있습니다. 참조 : An abstract class is a class that is declared abstract—it may or may not include abstract methods.참조 소스 : docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Devner

기술적 세부 사항과 구현에 대해 이야기하고 있지만 일반적인 OOP 측면에서 질문에 대답하지 않습니다
Billal Begueradj

26

개념적으로 말하면, 언어 별 구현, 규칙, 이점을 유지하고 누군가 또는 둘 다를 사용하여 프로그래밍 목표를 달성하면 코드 / 데이터 / 속성, blah blah, 단일 또는 다중 상속을 모두 포함하거나 가질 수 없습니다.

1- 추상 (또는 순수 추상) 클래스는 계층을 구현하기위한 것입니다. 비즈니스 오브젝트가 다소 구조적으로 유사 해 부모-자식 (계층 구조)의 관계 만 나타내는 경우 상속 / 추상 클래스가 사용됩니다. 비즈니스 모델에 계층 구조가 없으면 상속을 사용하지 않아야합니다 (여기서는 프로그래밍 로직에 대해 이야기하지 않습니다. 예를 들어 일부 디자인 패턴에는 상속이 필요함). 개념적으로 추상 클래스는 OOP에서 비즈니스 모델의 계층 구조를 구현하는 방법입니다. 인터페이스와는 아무런 관련이 없습니다. 실제로 추상 클래스와 인터페이스를 비교하는 것은 의미가 없습니다. 인터뷰에서 개념을 확인하기 위해 요청을 받았는데, 구현과 관련하여 다소 동일한 기능을 제공하고 프로그래머는 일반적으로 코딩에 더 중점을 둡니다. [추상화는 추상 클래스와 다르다는 점을 명심하십시오].

2- 인터페이스는 하나 이상의 기능 세트로 표시되는 완전한 비즈니스 기능인 계약입니다. 그것이 구현되고 상속되지 않은 이유입니다. 비즈니스 오브젝트 (계층 구조의 일부)는 여러 가지 완전한 비즈니스 기능을 가질 수 있습니다. 추상 클래스와는 아무런 관련이 없으며 일반적으로 상속을 의미합니다. 예를 들어, 사람은 RUN, 코끼리는 RUN, 조류는 RUN 등을 수행 할 수 있습니다. 계층 구조가 다른 모든 개체는 RUN 인터페이스 또는 EAT 또는 SPEAK 인터페이스를 구현합니다. 이러한 인터페이스를 구현하는 각 유형에 대한 추상 클래스를 가지고 구현할 수 있으므로 구현하지 마십시오. 계층 구조의 객체는 계층 구조와 관련이없는 기능 (인터페이스)을 가질 수 있습니다.

인터페이스는 다중 상속을 달성하거나 공개 동작을 노출하기 위해 발명되지 않았으며 순수한 추상 클래스는 인터페이스를 지배하지 않지만 인터페이스는 객체가 할 수있는 기능 (인터페이스의 기능을 통해)을 수행하며 추상 클래스는 부모의 핵심 구조 (속성 + 기능)를 가진 자식을 생성하는 계층의 부모

차이점에 대한 질문을 받으면 실제로 명시 적으로 요청하지 않는 한 언어 별 구현의 차이점이 아닌 개념상의 차이입니다.

두 면접관은 두 사람 사이에 한 줄의 직접적인 차이점을 기대하고 있었고 실패했을 때 ONE을 OTHER로 구현 하여이 차이를 이끌어 냈습니다.

추상 메소드 만 가진 추상 클래스가 있다면 어떨까요?


그것은이 질문에 대한 대답을 꽤 잘 요약합니다.
pranavn

기능 구현 대 구조 확장, 멋지다!
harshvchawla

21

.Net의 경우

두 번째 면접에 대한 귀하의 답변 또한 첫 번째에 대한 답변입니다 ... 추상 클래스는 구현을 가질 수 있으며 상태는 인터페이스가 할 수 없습니다 ...

편집 : 또 다른 참고로, 인터페이스를 '구현하도록 정의 된'클래스를 설명하기 위해 '서브 클래스'구문 (또는 '상속'구문)을 사용하지 않을 것입니다. 나에게 인터페이스는 클래스가 해당 인터페이스를 '구현'하도록 정의 된 경우 클래스가 준수해야하는 계약의 정의입니다. 그것은 아무것도 상속받지 않습니다 ... 당신은 명시 적으로 모든 것을 직접 추가해야합니다.


2
예! 상태! 그것이 두 번째 면접관이 인터페이스 내에서 "공개 변수"라는 이상한 방식으로 의미 한 바입니다. 어이! 추상 클래스는 상태를 가질 수 있고 인터페이스는 할 수 없습니다! 그렇습니다. 다른 사람들은 상속 방법 사이의 차이점에 대해서도 동의합니다. 이는 언급하지 않았지만 이미 알아 냈습니다. :) 감사합니다 여러분!
Houman

4
단순한 상태 이상 .... 추상 클래스에는 구현이있을 수 있습니다. 즉, 실제로 실행되고 무언가를 수행하는 코드가있는 메소드를 가질 수 있습니다. 기본 클래스의 인스턴스에 의해 상속되고 실행됩니다. 인터페이스와 함께
Charles Bretana

그 이상의 의미에서 Abstract 클래스는 인스턴스화 될 수 있으며 직접 클래스가 아닌 파생 클래스 정의를 사용하여 인스턴스화하면됩니다. 그러나 추상 클래스에 정의 된 상태 변수는 파생 클래스의 인스턴스를 새로 만들어서 생성 된 객체에서 인스턴스화됩니다. 이 인스턴스는 추상 클래스의 인스턴스이며 파생 클래스의 인스턴스입니다. 결국이 클래스에서 파생됩니다. 인터페이스에는 해당되지 않습니다.
Charles Bretana

인터페이스를 구현하도록 정의 된 클래스의 인스턴스를 새로 만들면 해당 인터페이스의 "인스턴스"가 아닙니다. 모든 구문은 컴파일러가 클래스의 코드를 검사하고 모든 동작 (메소드, 속성)을 확인하도록합니다. 인터페이스에 의해 정의 된, event, eventHandler 등)이 클래스 코드에서 구현되었습니다.
Charles Bretana

20

인터페이스 : 서로 관련되거나 관련되지 않을 수있는 구성 요소에 대한 규칙을 암시하려면 사용해야합니다.

장점 :

  1. 다중 상속 가능
  2. 컨텍스트에서 사용되는 정확한 종류의 객체를 노출하지 않음으로써 추상화를 제공합니다.
  3. 계약의 특정 서명으로 일관성을 제공합니다

단점 :

  1. 정의 된 모든 계약을 구현해야합니다.
  2. 변수 또는 대리자를 가질 수 없습니다
  3. 일단 정의되면 모든 클래스를 중단하지 않고 변경할 수 없습니다

추상 클래스 : 서로 관련된 구성 요소에 대한 기본 또는 기본 동작 또는 구현을 원할 때 사용해야합니다.

장점 :

  1. 인터페이스보다 빠름
  2. 구현에 유연성이 있음 (완전히 또는 부분적으로 구현할 수 있음)
  3. 파생 클래스를 깨지 않고도 쉽게 변경할 수 있습니다

단점 :

  1. 인스턴스화 할 수 없습니다
  2. 다중 상속을 지원하지 않습니다

더 빨리 정의하십시오. 중요합니까? 무엇을 의미합니까? 추상 클래스에서 함수 호출을위한 opcode가 인터페이스에서 함수 호출을위한 opcode보다 빠릅니까?
denis631

@ denis631 추상 클래스는 검색 및 호출이 인터페이스 메소드에 관련되어 있기 때문에 인터페이스보다 약간 빠릅니다. 이 coderanch.com/t/503450/java/abstract-class-faster-interface
bourax 웹 마스터

17

나는 당신이 디자인이 아닌 기술적 차이점을 제시했기 때문에 그들이 당신의 응답을 좋아하지 않는다고 생각합니다. 질문은 나에게 트롤 질문과 같습니다. 실제로 인터페이스와 추상 클래스는 완전히 다른 특성을 가지므로 실제로 비교할 수 없습니다. 인터페이스의 역할과 추상 클래스의 역할에 대한 비전을 알려 드리겠습니다.

interface : 보다 유지 관리 가능하고 확장 가능하며 테스트 가능한 응용 프로그램을 갖기 위해 계약을 보장하고 클래스 간 낮은 연결을 만드는 데 사용됩니다.

추상 클래스 : 동일한 책임의 클래스간에 일부 코드를 인수 분해하는 데만 사용됩니다. 클래스가 많은 책임을 처리하지 않아야 하기 때문에 OOP에서 다중 상속이 나쁜 이유 인 주된 이유입니다 ( 대신 구성 사용).

따라서 인터페이스는 실제 아키텍처 역할을하는 반면 추상 클래스는 거의 구현의 세부 사항 일뿐입니다 (물론 올바르게 사용하는 경우).


13
After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

문서에 따르면 추상 클래스에 추상 메서드 선언 만 포함 된 경우 대신 인터페이스로 선언해야합니다.

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

인터페이스의 변수는 기본적으로 공개 정적 및 최종 변수입니다. 추상 클래스의 모든 변수가 공용이라면 질문은 어떻게 구성 될 수 있습니까? 인터페이스의 변수와 달리 정적이 아니며 최종적이지 않을 수 있습니다.

마지막으로 위에서 언급 한 것들에 하나 이상의 포인트를 추가합니다. 추상 클래스는 여전히 클래스이며 단일 상속 트리에 속하지만 인터페이스는 다중 상속에 존재할 수 있습니다.


13
  1. 상호 작용:
    • 우리는 메소드를 구현 (또는 정의)하지 않으며 파생 클래스에서 수행합니다.
    • 인터페이스에서 멤버 변수를 선언하지 않습니다.
    • 인터페이스는 HAS-A 관계를 나타냅니다. 그것은 그들이 물체의 마스크라는 것을 의미합니다.
  2. 추상 클래스 :
    • 추상 클래스에서 메소드를 선언하고 정의 할 수 있습니다.
    • 우리는 그것의 생성자를 숨 깁니다. 즉, 직접 만든 개체가 없습니다.
    • 추상 클래스는 멤버 변수를 보유 할 수 있습니다.
    • 파생 클래스는 추상 클래스로 상속되며 파생 클래스의 객체는 마스크되지 않고 추상 클래스로 상속됩니다. 이 경우의 관계는 IS-A입니다.

이것은 나의 의견이다.


12

Jeffrey Richter가 C #을 통해 CLR에서 복사 한 ...

"기본 유형 또는 인터페이스를 설계해야합니까?"라는 질문을 자주받습니다. 답이 항상 명확한 것은 아닙니다.

다음은 도움이 될만한 몇 가지 지침입니다.

■■ IS-A 대 CAN-DO 관계 유형은 하나의 구현 만 상속 할 수 있습니다. 파생 유형이 기본 유형과 IS-A 관계를 주장 할 수없는 경우 기본 유형을 사용하지 마십시오. 인터페이스를 사용하십시오. 인터페이스는 CAN-DO 관계를 의미합니다. CAN-DO 기능이 다양한 객체 유형에 속하는 것으로 보이면 인터페이스를 사용하십시오. 예를 들어, 형식은 자체 인스턴스를 다른 형식 (IConvertible)으로 변환하고, 형식은 자체 인스턴스를 직렬화 (ISerializable) 할 수 있습니다. 값 형식은 System.ValueType에서 파생되어야하므로 파생 될 수 없습니다. 임의의 기본 클래스에서 이 경우, CAN-DO 관계를 사용하고 인터페이스를 정의해야합니다.

사용 편의성 일반적으로 개발자는 인터페이스의 모든 메소드를 구현하는 것보다 기본 유형에서 파생 된 새 유형을 정의하는 것이 더 쉽습니다. 기본 유형은 많은 기능을 제공 할 수 있으므로 파생 유형은 해당 동작에 대해 비교적 작은 수정 만 필요합니다. 인터페이스를 제공하는 경우 새 유형은 모든 멤버를 구현해야합니다.

일관성있는 구현 인터페이스 계약이 아무리 잘 문서화되어 있더라도 모든 사람이 계약을 100 % 올바르게 구현할 가능성은 거의 없습니다. 실제로 COM은이 문제로 인해 어려움을 겪기 때문에 일부 COM 개체는 Microsoft Word 또는 Windows Internet Explorer에서만 제대로 작동합니다. 좋은 기본 구현으로 기본 유형을 제공함으로써 작동하고 테스트가 잘된 유형을 사용하여 시작합니다. 그런 다음 수정이 필요한 부품을 수정할 수 있습니다.

■■ 버전 관리 기본 유형에 메소드를 추가하면 파생 된 유형이 새 메소드를 상속하며 작동하는 유형을 사용하여 시작하며 사용자의 소스 코드를 다시 컴파일 할 필요조차 없습니다. 인터페이스에 새 멤버를 추가하면 인터페이스 상속자가 소스 코드를 변경하고 다시 컴파일해야합니다.


1
@AbdullahShoaib는 누구나 할 수 있지만 할 수는 없지만 여기에는 차이점이 있습니다. 이것이 기본 이유입니다. 인터페이스가 필요합니다. 할 수있는 행동도 포함됩니다 abstract class.
overexchange

10

인터페이스는 서비스 또는 서비스 세트에 대한 계약을 정의합니다. 이 두 클래스는 인터페이스에 의해 정의 된 서비스 세트를 만족 시키겠다고 약속 했으므로 완전히 관련이없는 두 클래스가 동일한 인터페이스를 구현할 수 있지만 구현하는 인터페이스 유형의 매개 변수로 상호 교환 가능하게 사용될 수있는 수평 방식으로 다형성을 제공합니다. 인터페이스는 구현 세부 사항을 제공하지 않습니다.

추상 클래스는 서브 클래스의 기본 구조 및 선택적으로 부분 구현을 정의합니다. 추상 클래스는 추상 클래스를 상속하는 모든 클래스가 해당 추상 클래스의 인스턴스로 취급 될 수 있지만 다른 방식으로는 처리 할 수 ​​없다는 점에서 수직적이지만 지향적 인 방식으로 다형성을 제공합니다. 추상 클래스는 구현 세부 사항을 포함 할 수 있으며 종종 자체적으로 인스턴스화 할 수는 없으며 서브 클래스 만 "새로 작성"할 수 있습니다.

C #은 인터페이스 상속도 허용합니다.


1
가로세로 라는 용어를 사용하면 차이를 상상하기가 매우 명확 해졌습니다.
무한대

10

대부분의 답변 은 추상 클래스와 인터페이스 의 기술적 차이 에 중점을 두지 만 기술적으로 인터페이스는 기본적으로 일종의 추상 클래스 (데이터 또는 구현이없는 클래스)이므로 개념적 차이가 훨씬 흥미 롭습니다. 면접관은 후에있다.

인터페이스 입니다 계약 . "이것은 우리가 서로 대화하는 방법입니다"라고 지정합니다. 이 아니기 때문에 그것은 어떤 구현을 가질 수 없습니다 되어 있는 구현을 할 수 있습니다. 계약입니다. 그것은 같은.hC 헤더 파일 .

추상 클래스 이다 불완전한 구현 . 클래스는 인터페이스를 구현하거나 구현하지 않을 수 있으며 추상 클래스는 인터페이스를 완전히 구현하지 않아도됩니다. 구현이없는 추상 클래스는 쓸모 없지만 완전히 합법적입니다.

추상적 여부를 기본적으로 모든 클래스, 그것은 무엇에 관한 것입니다 인터페이스에 대해 반면, 당신이 그것을 사용하는 방법 . 예를 들어 Animal, 기본적인 대사 기능을 구현하고 구현하지 않고 호흡과 운동을위한 추상적 인 방법을 지정하는 추상 클래스 일 수 있습니다. 크롤링.Mount반면에, 어떤 종류의 동물인지 (또는 동물인지 전혀 모르는 상태에서) 동물을 타도록 지정할 수있는 인터페이스 일 수도 있습니다.

배후에서 인터페이스는 기본적으로 추상 메소드 만있는 추상 클래스이므로 중요하지 않습니다. 개념적으로 그들은 완전히 다른 역할을 수행합니다.


10

당신이 전문가의 이론적 지식을 가지고 있습니다, 나는 여기에 모든 반복에 많은 단어를 지출하고 있지 않다, 오히려 나에게 우리가 사용할 수없는 / 사용할 수있는 간단한 예제와 함께 설명하도록 Interface하고 Abstract class.

자동차의 모든 기능을 나열하는 애플리케이션을 설계한다고 가정하십시오. DigitalFuelMeter, 에어컨, 좌석 조정 등과 같은 일부 속성은 모든 자동차에 공통적이므로 다양한 점에서 공통 상속이 필요합니다. 마찬가지로 제동 시스템 (ABS, EBD)과 같은 일부 속성은 일부 자동차에만 적용 할 수 있으므로 일부 클래스의 상속 만 필요합니다.

아래 클래스는 모든 자동차의 기본 클래스 역할을합니다.

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

각 차량마다 별도의 수업이 있다고 가정하십시오.

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

Verna와 Cruze 자동차 (Alto에는 해당되지 않음)의 브레이크 기술을 상속 할 수있는 방법이 필요합니다. 둘 다 제동 기술을 사용하지만 "기술"은 다릅니다. 따라서 메소드를 Abstract로 선언하고 자식 클래스에서 구현해야하는 추상 클래스를 만들고 있습니다.

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

이제 우리는이 추상 클래스를 상속하려고 시도하고 제동 시스템의 유형은 Verna와 Cruze에서 구현됩니다.

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

위의 두 클래스에서 문제를 보시겠습니까? 이 메서드는 자식에서 메서드를 구현하더라도 C # .Net에서 허용하지 않는 여러 클래스에서 상속됩니다. 여기 인터페이스가 필요합니다.

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

구현은 다음과 같습니다.

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

이제 Verna와 Cruze는 인터페이스를 사용하여 고유 한 제동 기술로 다중 상속을 달성 할 수 있습니다.


4
이것은 예제 때문에 가장 좋은 설명 중 하나입니다.
Adam Mendoza

2
이것은 뇌를 건드리지 않고 나에게 의미가 있습니다. 방금 학생들을위한 자동차 예를 만들려고 노력했습니다. 시간을내어 함께 해주셔서 감사합니다.
tazboy

9

인터페이스는 특정 동작을 시행하는 간단한 방법입니다. 그것은 생각하는 한 가지 방법입니다.


8

이 답변은 너무 깁니다.

  • 인터페이스는 동작을 정의하기위한 것입니다.

  • 추상 클래스는 동작을 포함하여 사물 자체를 정의하기위한 것입니다. 그렇기 때문에 때때로 인터페이스를 상속받는 몇 가지 추가 속성으로 추상 클래스를 생성합니다.

또한 Java가 클래스에 대한 단일 상속 만 지원하지만 인터페이스에 제한을 두지 않는 이유도 설명합니다. 구체적인 대상은 다를 수 없지만 행동은 다를 수 있습니다.


7

1) 인터페이스는 순수한 추상 클래스로 볼 수 있지만 동일하지만 인터페이스를 구현하고 추상 클래스에서 상속하는 것과 동일하지 않습니다. 이 순수한 추상 클래스에서 상속 할 때 계층 구조-> 상속을 정의하고 있습니다. 인터페이스를 구현하면 인터페이스를 구현할 수 없으며 원하는 수만큼 인터페이스를 구현할 수 있지만 한 클래스에서만 상속 할 수 있습니다.

2) 인터페이스에서 속성을 정의 할 수 있으므로 해당 인터페이스를 구현하는 클래스에 해당 속성이 있어야합니다.

예를 들면 다음과 같습니다.

  public interface IVariable
  {
      string name {get; set;}
  }

해당 인터페이스를 구현하는 클래스에는 이와 같은 속성이 있어야합니다.


7

이 질문은 꽤 오래되었지만 인터페이스를 선호하는 다른 요점을 추가하고 싶습니다.

인터페이스는 추상 클래스 주입이 거의 지원하지 않는 모든 의존성 주입 도구를 사용하여 주입 할 수 있습니다.


1
DI 툴이 인터페이스를 구현하는 클래스를 주입 할 수 있다고 생각합니다. 이러한 도구 중 일부는 추상 클래스에서 파생 된 클래스를 삽입 할 수도 있고 불가능하다고 말하고 있습니까?
존 손더스

6

에서 내 다른 답변 , 대부분 다른 대 하나를 사용하는 경우 처리 :

내 경험에 따르면 인터페이스는 동일한 클래스 또는 메소드에 응답 해야하는 클래스가 여러 개있을 때 가장 잘 사용되므로 해당 클래스의 공통 인터페이스에 대해 작성된 다른 코드로 상호 교환 가능하게 사용할 수 있습니다. 인터페이스를 가장 잘 사용하는 것은 프로토콜이 중요하지만 기본 로직이 클래스마다 다를 수 있습니다. 그렇지 않으면 논리를 복제하는 경우 추상 클래스 또는 표준 클래스 상속을 고려하십시오.


6

인터페이스 유형과 추상 기본 클래스

Pro C # 5.0 및 .NET 4.5 Framework 책 에서 채택되었습니다 .

인터페이스 유형은 추상 기본 클래스와 매우 유사하게 보일 수 있습니다. 클래스가 abstract로 표시되면 모든 파생 유형에 다형성 인터페이스를 제공하기 위해 여러 추상 멤버를 정의 할 수 있습니다. 그러나 클래스가 추상 멤버 집합을 정의하는 경우에도 생성자, 필드 데이터, 비추 상 멤버 (구현 포함) 등을 자유롭게 정의 할 수 있습니다. 반면에 인터페이스에는 추상 멤버 정의 만 포함됩니다. 추상 부모 클래스에 의해 설정된 다형성 인터페이스는 파생 된 형식 만 추상 부모에 의해 정의 된 멤버를 지원한다는 점에서 한 가지 큰 제한이 있습니다. 그러나 더 큰 소프트웨어 시스템에서는 System.Object 이외의 공통 상위가없는 여러 클래스 계층을 개발하는 것이 매우 일반적입니다. 추상 기본 클래스의 추상 멤버는 파생 된 형식에만 적용되므로 동일한 다형성 인터페이스를 지원하도록 다른 계층 구조의 형식을 구성 할 방법이 없습니다. 예를 들어, 다음 추상 클래스를 정의했다고 가정하십시오.

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

이 정의가 주어지면 CloneableType을 확장하는 멤버 만 Clone () 메소드를 지원할 수 있습니다. 이 기본 클래스를 확장하지 않는 새 클래스 세트를 작성하면이 다형성 인터페이스를 얻을 수 없습니다. 또한 C #이 클래스에 대한 다중 상속을 지원하지 않는다는 것을 기억할 수 있습니다. 따라서 Car 및 CloneableType 인 MiniVan을 작성하려는 경우이를 수행 할 수 없습니다.

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

짐작 하시겠지만, 인터페이스 유형이 구출됩니다. 인터페이스를 정의한 후에는 모든 네임 스페이스 또는 어셈블리 (모든 .NET 프로그래밍 언어로 작성) 내의 모든 계층 또는 구조로 클래스 또는 구조로 구현할 수 있습니다. 보다시피, 인터페이스는 매우 다형성입니다. 시스템 네임 스페이스에 정의 된 ICloneable이라는 표준 .NET 인터페이스를 고려하십시오. 이 인터페이스는 Clone ()이라는 단일 메소드를 정의합니다.

public interface ICloneable
{
object Clone();
}

6

두 번째 질문에 대한 답변 : 기본적으로 public정의 된 변수 interfacestatic final기본적 public으로 abstract클래스 의 변수 는 인스턴스 변수입니다.


6

확실히 OOP에서 인터페이스와 추상 클래스의 동작을 이해하고 언어가 어떻게 처리하는지 이해하는 것이 중요하지만 각 용어가 정확히 무엇을 의미하는지 이해하는 것이 중요하다고 생각합니다. 당신은 상상할 수 있습니까if명령이 용어의 의미와 정확히 일치하지 않는다고 ? 또한 일부 언어는 인터페이스와 초록의 차이를 훨씬 더 줄입니다. 언젠가 두 용어가 거의 동일하게 작동하는 경우 적어도 두 언어의 위치와 이유를 스스로 정의 할 수 있습니다 사용.

일부 사전과 다른 글꼴을 읽으면 같은 용어에 대해 다른 의미를 갖지만 일반적인 정의가있을 수 있습니다. 이 사이트 에서 찾은이 두 가지 의미 가 정말 훌륭하고 적합하다고 생각합니다.

상호 작용:

개별적이고 때로는 호환되지 않는 요소들이 효과적으로 조정될 수있게하는 것 또는 상황.

요약:

더 광범위하거나 더 일반적인 것 또는 몇 가지 것의 본질적인 특성 자체에 집중하는 것; 본질.

예:

차를 샀는데 연료가 필요합니다.

여기에 이미지 설명을 입력하십시오

귀하의 자동차 모델은 XYZ장르 ABC인이므로 콘크리트 자동차, 자동차의 특정 인스턴스입니다. 자동차는 실물이 아닙니다. 실제로 특정 객체를 생성하는 것은 일련의 추상 표준 (품질)입니다. 요컨대, Car는 추상 클래스 이며, "자체 자체가보다 광범위하거나 일반적인 것의 본질적인 특성에 집중하는 것" 입니다.

자동차 수동 사양과 일치하는 유일한 연료를 사용하여 자동차 탱크를 채우십시오. 실제로, 연료를 넣는 것을 제한하는 것은 없지만 엔진은 지정된 연료로만 제대로 작동하므로 요구 사항을 따르는 것이 좋습니다. 요구 사항에 따르면 동일한 장르의 다른 자동차와 마찬가지로 허용됩니다.ABC 표준 연료 세트를 사용할 수 있습니다.

객체 지향 관점에서 ABC특정 장르의 자동차에 대한 구체적인 연료가 없기 때문에 장르 용 연료를 클래스로 선언해서는 안됩니다. 자동차가 추상 등급의 연료 또는 차량 연료를 수용 할 수는 있지만 기존 차량 연료 중 일부만이 자동차 설명서의 요구 사항을 구현하는 사양을 충족한다는 것을 기억해야합니다. 즉, 그들은 구현해야 인터페이스 ABCGenreFuel , "... 효과적으로 조정하기 위해 별도 때로는 호환되지 않는 요소 수를" .

추가

또한 클래스라는 용어의 의미를 명심해야한다고 생각합니다.이 용어는 (이전에 언급 한 동일한 사이트에서) 다음과 같습니다.

수업:

공통된 속성, 특성, 특성 또는 특성으로 인해 그룹을 구성하는 것으로 간주되는 많은 사람 또는 사물; 종류;

이런 식으로 클래스 (또는 추상 클래스)는 공통 속성 (인터페이스와 같은)만을 나타내지 않고 공통 속성을 가진 일종의 그룹을 나타내야합니다. 인터페이스는 종류를 나타낼 필요가 없습니다. 공통 속성을 나타내야합니다. 이런 식으로, 클래스와 추상 클래스는 어떤 종류를 나타 내기 때문에 인간처럼 포유류와 같이 종종 측면을 변경해서는 안되는 것을 나타내는 데 사용될 수 있다고 생각합니다. 종류가 자주 바뀌지 않아야합니다.


1
보풀이 너무 많으면 사람들이 이미 생각보다 혼동하게 만들지 마십시오.
간지이 2009

5

코딩 관점에서

추상 클래스에 추상 메소드 만있는 경우 인터페이스가 추상 클래스를 대체 할 수 있습니다. 그렇지 않으면 Abstract 클래스를 인터페이스로 변경하면 Inheritance가 제공하는 코드 재사용 성을 잃게됩니다.

디자인 관점에서

"Is a"관계이고 서브 세트 또는 모든 기능이 필요한 경우 추상 클래스로 유지하십시오. "해야 할"관계인 경우 인터페이스로 유지하십시오.

정책 시행, 코드 재사용 및 정책 등 필요한 것을 결정하십시오.


3

다른 차이점들 :

추상 클래스는 정적 메소드, 속성, 필드 등을 가질 수 있으며 연산자는 인터페이스를 가질 수 없습니다. 캐스트 연산자는 추상 클래스와의 캐스트를 허용하지만 인터페이스와의 캐스트는 허용하지 않습니다.

그래서 정적 클래스를 통해 구현되지 않았고 어떤 방식 으로든 인터페이스를 사용할 수없는 경우에도 추상 클래스를 자체적으로 사용할 수 있습니다.


Java에서 인터페이스는 멤버 변수를 가질 수 있지만 기본적으로 공용 정적이됩니다. 인터페이스는 정적 필드를 가질 수 있습니다.
Jitendra Vispute

예 인터페이스에는 정적 필드가있을 수 있습니다. 그러나 인터페이스는 정적 메소드를 가질 수 없습니다.
학습자
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.