2013-08-29 28 views
3

我必须设计一个数据结构,它会多次实现,并且我遇到了一个问题。Java:受保护的方法在接口之前

由于我的数据结构需要它的多个版本,我创建了一个抽象类,为所有实现奠定了基础。但是,数据结构也需要对某些部分进行设置。

问题变成如下:根据我的数据结构的实现,集合需要有不同的实现: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()方法变为公共,这是不可取的。
  • 使SetView只扩展AbstractSetView并且自己实现一切...两次。但是这需要我基本上包含HashSet和SingletonSet实现,作为一个非常难看的内部类。

当然,Java的设计者提出了一些解决方法,使我能够使用它们的内置Set实现?我忽略了什么?

回答

0

到目前为止给出的两个答案都为Set案例提供了解决方案和建议。然而,你可以在这个和其他类似情况下使用的模式(例如,你不是扩展一个JRE类,而是你自己的东西)是将接口拆分成公共的和内部的保护的。

在这种情况下,您的公共接口将被设置。

受保护的内部接口将是InternalSet,在AbstractEdge中声明,定义removeInternal方法。该方法将是“公开”的,但接口不需要。

然后,抽象的超类应该定义一个公共方法,它返回公共接口在你的子类之外使用,一个受保护接口只返回受保护接口供内部使用。

实现子类可以实现一个类,扩展你需要的任何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%的情况提供这些信息。恕我直言,他们的百分比是正确的。

要回答你的第二个问题:不要继承,特别是从库类中,当你真正需要的是组合。使AbstractEdge有一个成员protected Set backingSet;,它由子类实现了不同的Set实现。这意味着你不需要AbstractSetView及其子类。

否则,会员protected Set backingSet;可位于AbstractSetView