为什么子类不能访问基类的private成员(为什么要使用get,set方法)?为什么要这样设计?
2015-04-29 22:06
751 查看
为什么子类不能访问基类的private成员?为什么要这样设计?
stringclassjavaapieclipseobject看到很多朋友提问“为什么子类不能访问基类的private成员”?随后看到很多朋友回答“这是规范”“这是封装的特性”类似这样的回答。我觉得大家都是对的。但是有时候您需要关注提问的重点在于why?为什么Java要这样设计private?或者是Object Oriented为啥要这样设计这样的机制?
封装性:首先,private成员具有良好的封装性(encapsulation)。这个性质对于良好的设计来说是个重要的要素。因为良好的封装性会减小耦合的。服务代码可以定义public函数给客户代码。这样一来客户代码可以和服务代码并行开发。更重要的是,如果修改服务代码的内部实现也不需要改动客户代码。
子类也是客户代码:对于客户代码的理解最直接的就是调用这个类的代码,这个很好理解。更深入的理解就可以把客户代码延伸到这个类的子类。从这一点来说子类就是基类的客户代码。你定义了一个class,在里面写了些通用的方法,甚至申明了abstract方法要求别人来继承。这个时候基类里面的protect成员就是对外的API,因为这些方法对子类来说是可见的,你不能随意改动。这个时候如果这个成员是public或者protected就可能造成麻烦。对于API来说你不能随意改动。你能设想JDK里面的有些类的API改动的情况吗?至少我会抓狂的:)
访问权限扩大原则:延伸话题来说,还有就是Java对override的时候访问权限的限制。大家都知道Java的访问权限从小到大是:private-> default-> protected-> public。如果要override一个基类里面的方法,那么子类的这个方法的权限不能比被override的函数权限小。这样就导致一个隐性的问题:如果你的基类有public方法,那么它的子类里面都有这个方法的public属性。你不能把基类的这个方法private化。换句话说一旦定义了public函数,它的子类都要维护这个public方法。所以就算是方法也要小心地把它设为public。
当然如果这个基类到最终的子类都是你维护,或者这个类本身就是个非public的类,那么原则可以放宽。
顺便说一下,Eclipse有自动生成标准get/set函数的功能,所以生成get/set是很容易的事情,不要为了方便把成员都变成public。
譬如写了个基类Base,然后有人继承了Base:
[java] view
plaincopy
public class Base {
public String[] data;
}
class Sub extends Base{
public void show(){
System.out.println(Arrays.toString(this.getData()));
}
}
可是有一天你发觉用ArrayList更好,你就把Base改成:
[java] view
plaincopy
public class Base {
//public String[] data;
public ArrayList data;
}
然后所有Base的子类都无法编译,直接调用到子类data域的类也无法编译。这就是噩梦,客户端程序员会用眼光追杀你:)
回过头来想,如果当初Base的data域是private,由get/set来访问,那么你可以轻松的修改Base, 子类无需改动:
[java] view
plaincopy
public class Base {
//private String[] data;
private ArrayList<String> data;
public String[] getData() {
return (String[]) data.toArray();
}
public void setData(String[] data) {
this.data = new ArrayList<String>(Arrays.asList(data));
}
}
作者:卢声远<michaellufhl@yahoo.com.cn>
相关文章推荐
- 为什么子类不能访问基类的private成员?为什么要这样设计?
- 为什么子类不能访问基类的private成员?为什么要这样设计?
- 为什么子类不能访问基类的private成员?为什么要这样设计? .
- 为什么子类不能访问基类的private成员?为什么要这样设计?
- 为什么子类不能访问基类的private成员?为什么要这样设计?
- 为什么类和接口不能使用private和protected?接口的方法不能使用private、protected、default
- 对象的封装:public private protecte 访问修饰符+魔术方法__get(),__set()
- iOS - 重写set和get方法后,为什么使用时会发生无效?解析命名规范
- 为什么子类中不能访问另一个包中父类中的protected方法?
- 通过protected,private继承的子类不能通过基类指针进行访问。
- WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?
- WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?
- 为什么子类中不能访问另一个包中父类中的protected方法?
- Java中子类的基本继承方法,子类通过继承父类public方法,访问父类private成员
- WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法?
- 指针对虚基类成员变量的访问为什么不能直接通过offset访问,而需要通过vbtable间接访问?
- 派生类是否继承基类中的private成员,若继承为何不能在成员函数中访问?
- 类中使用get和set方法来控制成员变量,而不将成员变量的权限设为public的原因?
- 【封装】java中为什么要将属性进行私有化,又使用set和get方法来设置和获取属性呢?
- oc中成员变量的set/get方法 以及 属性点语法的使用