勿让儿童接触:从继承中删除受保护的字段

Ant*_*nyW 7 java inheritance encapsulation

本着精心设计的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.
}
Run Code Online (Sandbox Code Playgroud)

我已经发现,我可以通过使场撤销访问private finalMyBaseClass.然而,这也妨碍了使用超级类提供的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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

注意:我也知道,如果该字段是private首先使用protected访问器制作的,那么这将是一个非问题.可悲的是,我无法控制这一点.

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

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

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

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

Woo*_*ody 6

这对你来说可能是不可能的,但如果你可以从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....
Run Code Online (Sandbox Code Playgroud)

等等


Sle*_*led 0

如何限制我的孩子对受保护变量的访问,同时仍然能够私下操作它并公开设置它?

所以你希望公众比你拥有更多的权利?你不能这样做,因为他们总是可以调用公共方法......它是公共的。

  • @SvetlinZarev 显然你懒得读这篇文章。不是一个选择。 (2认同)