书上的一段代码如下:class TwoDShape
{
  private double width;
  private double height;
  
  double getWidth() {return width;}
  double getHeight() {return height;}
}class Triangle extends TwoDShape
{
  double area() 
  {
    return getWidth() * getHeight() / 2;
  }
}
书上用private来修饰父类的域,然后子类中通过调用父类的public方法(accessor)来间接使用父类的域,这样感觉很奇怪啊,为什么不直接把父类中的域用protected来修饰,然后在子类中直接调用呢?代码如下:class TwoDShape
{
  protected double width;
  protected double height;
  
  double getWidth() {return width;}
  double getHeight() {return height;}
}class Triangle extends TwoDShape
{
  double area() 
  {
    return width * height / 2;
  }
}
书上既然使用private,是不是有什么特别的好处呢?或者说,从设计模式上来考虑,使用private更好么?

解决方案 »

  1.   

    protected 是包访问,在同一包里的其他类都可以访问。
    让其他类能够访问到自己的域是很危险的,可以随意的进行修改。
    改用getxxx(),只是可以读,不能写。
      

  2.   

    在实际应用中,要谨慎使用protected属性。假设需要将设计的类提供给其他程序员使用,而在这个类中设计了一些受保护域,那么其他程序员就有可能由这个类再派生出新类,并访问其中的受保护域。在这种情况下,如果需要对这个类的实现进行修改,就必须通知所有使用这个类的程序员。这违背了OOP提倡的数据封装原则。
      

  3.   

    protected 修饰的方法和属性和默认权限方法和属性的区别在于:在包外的子类可以继承protected 方法和属性,而且被继承的protected 方法和属性,在子类中仍然是protected(如果方法没有被override),但是要注意的是,我这里说它们仍然是protected,是从它们可以由该子类的包外的子类继续继承的递归性角度来说的,实际上它们的可见范围和该子类中新定义的protected 方法和属性是有区别的。不同之处在于在该子类中新定义的protected 方法和属性对该子类所在的包是可见的。而从父类中继承的protected 方法和属性在该子类所在的包中仅仅对该子类是可见的,同时另外它们还享有被继承前的可见范围(即被被继承前的可见范围仍然保持。这让人想起oop中的一个原则,方法和属性被继承后,其可见的范围只能扩大,不能缩小)。比如某类中定义某个protected方法,那么在该类所在的包中是可以访问该类的包外的子类的通过继承得到的该protected方法的(尽管该子类是在包外)。同时不可以在该类(代号A)的包外定义的某个类B中调用类A的子类SA的继承该类得到的该protected 方法(类B可以是A子类也可以不是A子类,类SA可以是在任何一个包中,但是B和SA是不同的两个类)。
      

  4.   

    从良好的封装角度来考虑 还是private比较安全 这样子类和同包内的其他类的对象就无法直接访问该变量了。因为面向对象的设计强调通过对象的方法去访问变量,而不是直接通过实例本身去操作变量。当然了,如果你有特殊需求,用protected修饰,那也是业务需要,无可厚非。
      

  5.   

    一般类中的属性都要定义为private,然后提供公有的方法供其他类来访问,这是出于数据保护的需要。
      

  6.   

    ZangXT,火龙果,老紫竹,李晗等前辈可以提供点看法么?
      

  7.   

    如果说private这么重要的话,那引入protected又有什么用呢?到底什么情况下才用protected呢?
      

  8.   

    突然觉得,变量field通常应该声明为private,同时提供protected的方法给子类来访问/修改变量,不知这种想是否正确呢?
      

  9.   

    看过API文档的话 你肯定看到过protected修饰的变量和方法 特殊需要而已 凡事没有绝对的
      

  10.   

    多谢楼上各位前辈的解答,可是,ZangXT,火龙果,老紫竹等大侠可以来个最后的定论么?
      

  11.   

    父类的属性一般要让子类继承的,所以protected好
      

  12.   

    private是一种安全的做法,成员对象会把自己隐藏起来。
    java中能不用继承最好不要用继承,你那个类的方法在一般程序是不会用的,
    对于运算,可以考虑使用组合设计模式。
    没事多看Thinking in java
      

  13.   

    从设计上来说,你写的是正确的!
    private 根本无法让子类继承后得到,
    继承其实是针对实例来说,继承,为什么要去继承父类,无非就是想不劳而获的得到一些资源,
    其实java里实现也是这样的,继承以后会先实例化父类,而后子类就可以有父类的资源。其实java很多父类里源码很多都是protected修饰的。 private double width;
      private double height;显然是设计上不正确,因为底和高三角形也有!