java – 远离儿童:无法从继承中删除受保护的字段

前端之家收集整理的这篇文章主要介绍了java – 远离儿童:无法从继承中删除受保护的字段前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
本着精心设计的OO的精神,我所延伸的某个类别已经标志着其中一个领域受到保护.这个班级还慷慨地提供了一个公共二传手,但没有吸气剂.

我正在使用一个基类扩展这个类,而基类又由几个孩子扩展.我如何限制从我的孩子访问受保护的变量,同时仍然可以私下操纵它并公开设置它?

见下面的例子:

public abstract class ThirdPartyClass {
  protected Map propertyMap;

  public void setPropertyMap(Map propertyMap){
    this.propertyMap= propertyMap;
  }

  // Other methods that use propertyMap.
}

public abstract class MyBaseClass extends ThirdPartyClass{
// Accessor methods for entries in propertyMap.
  public getFoo(){
    propertyMap.get("Foo");
  }

  public getBar(){
    propertyMap.get("Bar");
  }

 // etc...
}

public class OneOfManyChildren extends MyBaseClass {
// Should only access propertyMap via methods in MyBaseClass.
}

我已经发现我可以通过在MyBaseClass中创建字段private final来撤销访问权限.然而,这也妨碍了使用超级类提供的setter.

我能够通过下面的“聪明”来规避这种限制,但它也会导致维护相同地图的两个副本以及复制每个元素的O(n)操作.

public abstract class MyBaseClass extends ThirdPartyClass{

  private final Map propertyMap = new HashMap(); // Revokes access for children.

  /** Sets parent & grandparent maps. */
  @Override
  public final void setPropertyMap(Map propertyMap){
    super.setPropertyMap(propertyMap);
    this.propertyMap.clear();
    this.propertyMap.putAll(propertyMap);
  }
}

有没有更好的方法来实现这一目标?

注意:这只是真实问题的一个示例:如何在不保留多个副本的情况下限制对受保护字段的访问?

注意:我也知道,如果该字段首先是私有的,并且具有受保护的访问者,那么这将是一个非问题.可悲的是,我无法控制.

注意:需要IS-A关系(继承).

注意:这可以轻松应用于任何Collection,DTO或复杂对象.

那些误解这个问题的隐喻:

这类似于祖父母有一个饼干罐,他们可以让所有家庭成员和他们家中的任何其他人(受保护).有孩子的父母进入房子,并且由于他们自己的原因,他们希望防止他们的孩子在恶心的情况下进入饼干罐.相反,孩子应该向父母询问巧克力饼干并看到它神奇地出现;同样是糖饼干或奥利奥.他们永远不需要知道饼干都存放在同一个罐子里,或者甚至还有一个罐子(黑盒子).如果罐子属于父母,如果祖父母可以被说服收起饼干,或者如果祖父母本身不需要访问,那么这可以很容易地实现.如果没有创建和维护两个相同的罐子,那么如何才能限制儿童进入,而父母和儿童则不受阻碍.祖父母?

解决方法

这对你来说可能是不可能的,但如果你可以从ThirdPartyClass派生一个接口并让ThirdPartyClass实现它呢?

然后通过委托私有成员ThirdPartyClassImpl实现接口,使MyBaseClass充当装饰器.

public interface ThirdParty ...


public class ThirdPartyClass implements ThirdParty



public class MyBaseClass implements ThirdParty {

    private ThirdParty decorated = new ThirdPartyClass();



 public class SubclassOne extends MyBaseClass....

等等

猜你在找的Java相关文章