2013-08-29 4 views
3

여러 번 구현할 데이터 구조를 디자인해야하는데 문제가 발생했습니다.Java : Protected Method Before Interface

내 데이터 구조에 여러 버전이 있어야하므로 모든 구현에 대한 기본 지식을 제공하는 추상 클래스를 만들었습니다. 그러나 데이터 구조에는 특정 부분의 설정보기가 필요합니다.

다음과 같이 문제가 발생합니다. 내 데이터 구조의 구현에 따라 세트가 서로 다른 구현을 필요로합니다. HashSet 또는 Collections.SingletonSet입니다. 그러면 두 개의 구현 데이터 구조가 항목을 추가 또는 제거 할 때 추가 작업을 수행하기 위해이 비트를 확장합니다. 그러나 추상 데이터 구조에는이 추가 작업이 수행되지 않도록이 집합에서 요소를 내부적으로 제거하는 방법이 필요합니다. 이를 위해 보호 된 메소드를 세트에 추가하고 싶습니다. 그러나 그렇게 할 수는 없습니다!

는 설명하기

, 여기에 내가 만드는거야 자료 구조의 유형에 관한 몇 가지 예제 코드입니다 :

public abstract class AbstractEdge { 
    public abstract AbstractSetView destination(); //Gives a subclass of AbstractSetView in implementations. 

    public void doStuff() { 
     destination().removeInternal(foo); 
    } 

    public abstract class AbstractSetView implements Set<Vertex> { 
     protected abstract void removeInternal(Vertex vert); 
    } 
} 

public class Edge extends AbstractEdge { 
    public SetView destination() { 
     return new SetView(); 
    } 

    public class SetView extends AbstractSetView,Collections.SingletonSet<Vertex> { //Doesn't work this way. 
     protected void removeInternal(Vertex vert) { 
      //Do stuff. 
     } 
    } 
} 

public class HyperEdge extends AbstractEdge { 
    public SetView destination() { 
     return new SetView(); 
    } 

    public class SetView extends AbstractSetView,HashSet<Vertex> { //Doesn't work this way. 
     protected void removeInternal(Vertex vert) { 
      //Do stuff. 
     } 
    } 
} 

이 내가 생각했던 옵션입니다

  • 위와 같이 여러에서 연장은 수업은 허용되지 않습니다.
  • AbstractSetView를 인터페이스로 만들면 removeInternal() 메서드가 public이되므로 바람직하지 않습니다.
  • SetView는 AbstractSetView 만 확장하고 모든 것을 직접 구현합니다 ... 두 번. 그러나 이것은 기본적으로 HashSet 및 SingletonSet 구현을 내부 클래스로 포함해야하는데, 이는 매우 추악합니다.

분명히 Java 설계자가 내장 된 Set 구현을 사용할 수있게하려면이 방법을 사용 했습니까? 나는 무엇을 간과하고 있는가?

답변

0

두 답변은 Set 케이스에 대한 해결책과 조언을 제공합니다. 그러나이 상황과 다른 유사한 상황에서 사용할 수있는 패턴 (예 : JRE 클래스를 확장하지 않고 자신의 물건)은 인터페이스를 공용 및 내부 보호 된 인터페이스로 분할하는 것입니다.

이 경우 공용 인터페이스가 설정됩니다.

보호 된 내부 인터페이스는 InternalSet이며, AbstractIndge 내부에 선언되어 removeInternal 메서드를 정의합니다. 이 메소드는 "public"이지만 인터페이스가 될 필요는 없습니다.

그런 다음 추상 수퍼 클래스는 서브 클래스 외부에서 사용할 공개 인터페이스를 반환하는 public 메소드와 내부 사용만을 위해 보호 된 인터페이스를 반환하는 보호 된 메소드를 정의해야합니다.

하위 클래스를 구현하면 클래스를 구현하고 필요한 Set를 확장하고 보호 된 클래스를 구현 한 다음 두 메서드에서 인스턴스를 반환 할 수 있습니다.

JRE 클래스의 구성 또는 상속 중에서 선택하는 것은 모두 사용자의 것이며,

+0

downvote 경우이 방법은 아마도 둘 다 뭔가를 배울 수 있습니다. –

2

아니요, 장애물, 문제 또는 제한 사항이 없기 때문에 "이 문제를 해결하지 못했습니다". 그 (것)들에 따르면, 실제로 상응하는 무엇이 구성 될 때 사용되는 시간의 적어도 85 %이기 때문에 다중 상속은 언어에서 진짜로 필요하지 않았다. 나머지 사례의 14 %는 인터페이스의 사용과 합성의 비 자연적 사용을 통해 해결 될 수 있으며 코드 복제를 통해 1 %가 해결 될 수 있습니다. 사실 : 나중에는 U.G.L.Y입니다. R.E.D.U.N.D.A.N.T. U.N.S.A.F.E. 등이 있었지만 주요 목적은 임베디드 장치에서도 구현할 수있는 작은 언어를 만드는 것이 었습니다. 그들은 단지 1 %의 사례 만 포기하려고하지 않았습니다. IMHO, 그 비율은 대략 맞았습니다.

두 번째 질문에 대답하려면 특히 라이브러리 클래스에서을 상속하지 말아야합니다. 실제로 필요한 것은 컴포지션 일 때입니다. AbstractEdge에는 서브 클래스가 다른 Set 구현으로 초기화되는 protected Set backingSet; 구성원이 있습니다. 이는 AbstractSetView 및 그 하위 클래스가 필요하지 않음을 의미합니다.

그렇지 않으면 회원 protected Set backingSet;AbstractSetView에 있습니다.