【问题标题】:Protected field alternatives in Java?Java中的受保护字段替代方案?
【发布时间】:2012-07-01 04:35:28
【问题描述】:

我有一个在超类中使用受保护字段的代码。我怎样才能避免它,因为我认为所有字段都应该是私有的?

 /** "Abstract Builder" */
 abstract class PizzaBuilder {
    protected Pizza pizza;

    public Pizza getPizza() { return pizza; }
    public void createNewPizzaProduct() { pizza = new Pizza(); }

    public abstract void buildDough();
    public abstract void buildSauce();
    public abstract void buildTopping();
 }

 /** "ConcreteBuilder" */
 class HawaiianPizzaBuilder extends PizzaBuilder {
    public void buildDough()   { pizza.setDough("cross"); }
    public void buildSauce()   { pizza.setSauce("mild"); }
    public void buildTopping() { pizza.setTopping("ham+pineapple"); }
 }

 /** "ConcreteBuilder" */
 class SpicyPizzaBuilder extends PizzaBuilder {
    public void buildDough()   { pizza.setDough("pan baked"); }
    public void buildSauce()   { pizza.setSauce("hot"); }
    public void buildTopping() { pizza.setTopping("pepperoni+salami"); }
 }

【问题讨论】:

  • 你可以通过改变你的想法来避免这个问题。以预期的方式使用受保护的字段并没有错。
  • 能否在超类中编写一个setter和getter,然后使用super.getter方法来访问它们?
  • @MichaelMyers:感谢您的回答。但是这段代码允许同一个包中的所有类访问这个受保护的字段,这可能很危险。
  • @Logan:感谢您的回答,但所有类都可以通过 setter/getter 方法访问该字段。但我认为这个解决方案比原来的更好。

标签: java protected


【解决方案1】:

在子类中使用getPizza()

所以:

 public void buildDough()   { pizza.setDough("cross"); }

变成

public void buildDough()   { getPizza().setDough("cross"); }

【讨论】:

    【解决方案2】:

    您始终可以公开夏威夷和 Spicy 比萨制造商并保护比萨场。

    public abstract class PizzaBuilder {
        protected Pizza pizza;
        ...
     }
    
     /** "ConcreteBuilder" */
     public class HawaiianPizzaBuilder : PizzaBuilder {
         ...
     }
    
     /** "ConcreteBuilder" */
     public class SpicyPizzaBuilder : PizzaBuilder {
         ...
     }
    

    【讨论】:

    • 这没有任何意义。如果没有某种访问权限,无论是受保护的还是 getter/setter 方法,HawaiianPizzaBuilder 或 SpicyPizzaBuilder 都无法访问私有的“pizza”成员。
    • 对,我的意思是受保护。对不起。
    【解决方案3】:

    您这样回复评论:

    @Logan:感谢您的回答,但所有类都可以通过 setter/getter 方法访问该字段。但我认为这个解决方案比原来的更好。

    如果您想阻止这种情况,那么答案可能是更改 getter 方法的可见性,而根本不提供 setter。


    实际上,整体设计看起来有点奇怪。你有一个create 方法,它不返回它创建的对象,并且没有明显的方法可以调用子类的构建方法。 (也许您应该“审查”工厂对象设计模式。)

    在这个级别上重新思考将清楚地表明,pizza 变量及其 getter 可以而且应该从外部视图中隐藏。

    【讨论】:

      猜你喜欢
      • 2016-06-25
      • 1970-01-01
      • 2010-12-29
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      相关资源
      最近更新 更多