문제

이것은 이것에 대한 다소 후속 질문입니다. 질문.

다음과 같은 상속 트리가 있다고 가정합니다.

Car -> Ford -> Mustang -> MustangGT

인터페이스를 정의하면 이점이 있습니까? 이 수업 중?예:

ICar -> IFord -> IMustang -> IMustangGT

아마도 다른 수업(예: Chevy) 구현하고 싶습니다 Icar 또는 IFord 그리고 어쩌면 심지어 IMustang, 하지만 아마도 그렇지 않을 것입니다 IMustangGT 너무 구체적이기 때문이다.이 경우 인터페이스가 불필요한가요?

또한 구현하려는 모든 클래스는 IFord 확실히 다음에서 상속하여 하나의 상속을 사용하고 싶을 것입니다. Ford 코드가 중복되지 않도록.그것이 주어진다면, 또한 구현하면 어떤 이점이 있습니까? IFord?

도움이 되었습니까?

해결책

내 경험상, 인터페이스는 여러 클래스가있을 때 각각 동일한 방법이나 방법에 응답 해야하는 여러 클래스가 있으면 해당 클래스의 공통 인터페이스에 대해 다른 코드가 상호 교환 적으로 사용할 수 있도록하는 데 가장 적합합니다. 인터페이스를 가장 잘 사용하는 것은 프로토콜이 중요하지만 클래스마다 기본 논리가 다를 수 있습니다. 그렇지 않으면 논리를 복제하는 경우 대신 추상 클래스 또는 표준 클래스 상속을 고려하십시오.

그리고 질문의 첫 번째 부분에 대한 응답으로 각 수업에 대한 인터페이스를 만드는 것이 좋습니다. 이것은 당신의 클래스 구조를 불필요하게 혼란시킬 것입니다. 인터페이스가 필요하다면 나중에 항상 추가 할 수 있습니다. 도움이 되었기를 바랍니다!

아담

다른 팁

나는 또한 동의합니다 Adamalex의 반응 해당 인터페이스는 특정 방법에 응답 해야하는 클래스별로 공유해야합니다.

클래스가 비슷한 기능을 가지고 있지만 조상 관계에서 서로 직접 관련이없는 경우, 인터페이스는이 기능을 둘 사이의 기능을 복제하지 않고 클래스에 추가하는 좋은 방법이 될 것입니다. (또는 미묘한 차이 만있는 여러 구현이 있습니다.)

우리는 자동차 비유를 사용하는 동안 구체적인 예입니다. 다음 수업이 있다고 가정 해 봅시다.

Car -> Ford   -> Escape  -> EscapeHybrid
Car -> Toyota -> Corolla -> CorollaHybrid

자동차는 가지고 있습니다 wheels 그리고 할 수 있습니다 Drive() 그리고 Steer(). 따라서 이러한 방법은 다음에 존재해야합니다 Car 수업. (아마 Car 수업은 추상 수업이 될 것입니다.)

줄을 서서, 우리는 Ford 그리고 Toyota (아마도 아마도 자동차의 엠블럼 유형의 차이로 구현되었을 것입니다. 아마도 아마도 추상 클래스 일 것입니다.)

그런 다음 마침내 우리는 a Escape 그리고 Corolla 수업은 자동차로 완전히 구현 된 클래스입니다.

이제 우리는 어떻게 만들 수 있습니까? 잡종 차량?

우리는 서브 클래스를 가질 수 있습니다 Escape 그건 EscapeHybrid a FordsHybridDrive() 방법 및 서브 클래스 Corolla 그건 CorollaHybrid ~와 함께 ToyotasHybridDrive() 방법. 이 방법은 기본적으로 동일한 작업을 수행하지만 다른 방법이 있습니다. 왝. 우리가 그보다 더 잘할 수있는 것 같습니다.

하이브리드에 a가 있다고 가정 해 봅시다 HybridDrive() 방법. 우리는 완벽한 세상에서 두 가지 다른 유형의 하이브리드를 갖고 싶지 않기 때문에 IHybrid a HybridDrive() 방법.

그래서, 우리가 만들고 싶다면 EscapeHybrid 또는 CorollaHybrid 수업, 우리가해야 할 일은 구현 IHybrid 상호 작용.

실제 예를 들어, Java를 살펴 보겠습니다. 다른 객체와 객체를 비교할 수있는 클래스는 Comparable 상호 작용. 이름에서 알 수 있듯이 인터페이스는 클래스에 대한 것입니다. 유사한, 따라서 이름은 "비교 가능"입니다.

관심있는 문제로, a 자동차 예 에 사용됩니다 인터페이스 교훈 자바 튜토리얼.

해당 인터페이스를 전혀 구현해서는 안됩니다.

클래스 상속은 설명합니다 이 대상 ~이다 (예 : 그것은 정체성입니다). 이것은 괜찮지 만 대부분의 경우 어떤 대상이든 ~이다, 대상보다 훨씬 덜 중요합니다 하다. 인터페이스가 들어오는 곳입니다.

인터페이스가 설명해야합니다 이 대상 하다), 또는 그것이 어떻게 작용하는지. 이것은 행동이라는 것을 의미합니다.

따라서 좋은 인터페이스 이름은 일반적으로 형식이어야합니다. IDriveable, IHasWheels, 등등. 때때로이 행동을 설명하는 가장 좋은 방법은 잘 알려진 다른 대상을 참조하는 것이므로 "이들 중 하나와 같은 행동"이라고 말할 수 있습니다 (예 : IList) 그러나 그 형태의 명명은 소수입니다.

그 논리가 주어지면 시나리오 인터페이스 상속 의미가있는 것은 객체 상속 의미가 있습니다. 종종 이러한 시나리오는 서로 관련이 없습니다.

당신이 실제로 필요한 인터페이스를 통해 생각하는 데 도움이되기를 바랍니다 :-)

나는 당신이 언급해야 할 것들에 대한 인터페이스 만 만들고 있다고 말하고 싶습니다. 자동차에 대해 알아야 할 다른 클래스 나 기능이있을 수 있지만 포드에 대해 알아야 할 것이 얼마나 자주 있을까요?

필요하지 않은 물건을 만들지 마십시오. 그것이 당신이 인터페이스가 필요하다는 것이 밝혀지면, 돌아가서 그들을 만들기위한 작은 노력입니다.

또한, Pedantic 측면에서, 나는 당신이 실제로이 계층처럼 보이는 것을 만들지 않기를 바랍니다. 이것은 상속을 사용해야하는 것이 아닙니다.

해당 수준의 기능이 필요할 때만 생성하세요.

리팩토링 코드는 항상 진행 중인 프로세스입니다.

필요한 경우 인터페이스로 추출할 수 있는 도구가 있습니다.예를 들어 http://geekswithblogs.net/JaySmith/archive/2008/02/27/refactor-visual-studio-extract-interface.aspx

인터페이스를 구현하는 클래스의 구성원으로 ICAR과 나머지 (Make = Ford, Model = Mustang 및 물건)를 만드십시오.

Ford 클래스와 GM 클래스와 예를 들어 GM 클래스를 갖고 싶을 수도 있고 둘 다 ICAR을 구현하여 Polymorphism을 사용하여 확인 경로를 내려 가고 싶지 않습니다. Make == Whatever, 그것은 당신의 스타일에 달려 있습니다.

어쨌든 - 내 생각에, 그것들은 다른 방향이 아닌 자동차의 속성입니다. 브레이크, 속도 등 메소드가 일반적이기 때문에 하나의 인터페이스 만 필요합니다.

포드가 다른 차가 할 수없는 일을 할 수 있습니까? 나는 그렇게 생각하지 않습니다.

나는 첫 두 레벨의 ICAR과 IFORD를 만들고 두 번째 레벨에서 인터페이스가 필요할 때까지 두 번째 레벨을 내버려 두었습니다.

객체가 문제 영역 내에서 서로 상호 작용 해야하는 방법에 대해주의 깊게 생각하고 특정 추상 개념을 둘 이상 구현 해야하는지 고려하십시오. 인터페이스를 사용하여 다른 객체가 상호 작용하는 개념에 대한 계약을 제공합니다.

예를 들어, 포드는 아마도 제조업체이고 머스탱은 제조업체 포드가 사용하는 모델 이름 값이므로 다음과 같은 것을 가질 수 있습니다.

ivehichle-> carimpl, Motorbikeimpl -HAS -A 제조업체 HAS -MANY MODELAME

이 답변에서 인터페이스와 클래스의 차이, 나는 그것을 설명했다 :

  • 인터페이스는 개념을 노출시킵니다 ~이다 ( "무엇 ~이다"편집 시간에 유효하고) 가치 (myinterface x = ...)
  • 클래스는 개념을 드러냅니다 하다 (실제로 런타임에 실행), 값 또는 객체에 사용됩니다 (MyClass x 또는 amyclass.method ())

따라서 포드의 'Ford'변수 ( 'value'개념)에 저장해야한다면 Ford의 다른 하위 클래스를 만들면 Iford를 만드십시오. 그렇지 않으면 실제로 필요할 때까지 귀찮게하지 마십시오.

그것은 하나의 기준입니다 : 그것이 충족되지 않으면, Iford는 아마도 쓸모가 없을 것입니다.
그것이 충족되면, 이전 답변에 노출 된 다른 기준이 적용됩니다. 포드가 자동차보다 더 풍부한 API를 가지고 있다면, iford는 다형성 목적에 유용합니다. 그렇지 않다면 ICAR로 충분합니다.

내 관점에서 인터페이스는 클래스가 특정 서명을 구현하거나 (생각하고 싶을 때) 나에게 특정 "행동"을 구현해야한다는 요구 사항을 시행하는 도구가 있습니다. 개인 대명사, 그리고 나는 내 인터페이스를 그 식으로 읽을 수 있도록 내 인터페이스의 이름을 지정하려고 노력합니다 ... icanfly, iknowhowtopersistmyself iamdisplayable 등 수업. 나는 공개 서명 (행동)을 분석 한 다음 멤버를 더 작은 논리적 그룹으로 분리합니다 (예 : 예제 사용), iusefuel, iCarrypassengers, isteerable, iccelerate, iDepreciate 등과 같은 (예제 사용)와 같이 더 좋습니다. 내 시스템의 다른 클래스에 대한 인터페이스

일반적으로, 이것에 대해 생각하는 가장 좋은 방법 (그리고 OO의 많은 질문)은 계약의 개념에 대해 생각하는 것입니다.

계약은 각 당사자가 충족 해야하는 특정 의무를 제시하는 두 (또는 그 이상의) 당사자 간의 계약으로 정의됩니다. 프로그램에서 이것은 수업이 제공 할 서비스와 서비스를 얻기 위해 수업을 제공 해야하는 것입니다. 인터페이스는 인터페이스를 구현하는 모든 클래스가 만족해야한다는 계약을 명시합니다.

그러나 그 점을 염두에두고, 당신의 질문은 당신이 사용하는 언어와 무엇을하고 싶은지에 달려 있습니다.

수년간의 OO (오, 마이 갓, 30 년)를 한 후에는 보통 모든 계약, 특히 Java에서 모든 계약에 대한 인터페이스를 작성할 것입니다. 테스트가 훨씬 쉬워지기 때문입니다. 수업을위한 인터페이스가 있으면 빌드 할 수 있습니다. 거의 사소하게 물체를 조롱합니다.

인터페이스는 일반적인 공개 API이며 사용자는이 공개 API를 사용하는 것으로 제한됩니다. 사용자가 유형 별 방법을 사용하도록 의도하지 않는 한 IMustangGT, 당신은 인터페이스 계층 구조를 다음으로 제한 할 수 있습니다. ICar 그리고 IExpensiveCar.

인터페이스와 추상 클래스에서만 상속됩니다.

두 개의 클래스가있는 경우 거의 동일하며 다른 개체 구매와 함께 대부분의 방법, 사용 및 인터페이스를 구현해야합니다.
머스탱 클래스가 너무 다르면 인터페이스 ICAR뿐만 아니라 Imustang도 만듭니다.
그래서 Class Ford와 Mustang은 ICAR에서 물려받을 수 있으며 ICAR의 Mustang과 Mustanggt 그리고 이모 스탕.

클래스 포드를 구현하고 메소드가 머스탱과 동일하다면 Mustang에서 구입하십시오.

class Ford{
  public function Foo(){
    ...
    Mustang mustang  = new Mustang();
    return mustang.Foo();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top