首页 > 其他 > 详细

举一个例子说说为什么要封装

时间:2014-04-10 17:58:07      阅读:417      评论:0      收藏:0      [点我收藏+]
1、访问权限
    private->default->protected->public分别对应类内部访问权限、包访问权限、不同包的子类访问权限(相同包同之前的级别)、全局访问权限。 类的绝大多数属性使用private修饰,此外有些方法只是用于辅助实现该类的其他方法,这些"工具"方法也应该使用private修饰。 如果某个类主要用作其他类的父类,该类包含的绝大数方法可能仅仅希望被其子类重写,而不想被外界直接调用,则应该使用protected修饰。希望暴露出来给其它类自由调用的方法应该使用public修饰,顶级类通常给其它类自由使用,所以绝大数顶级类使用public修饰。类的构造器通过使用public修饰暴露给其他类以创建该类的对象。
2、理解封装(面向对象三大特征之一,另外两个是继承和多态)封装是指将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作访问。

3、控制对成员的访问权限有两个原因。

第一是为了使用户不要碰那些他们不该碰的部分这些部分对于类的内部操作是必要的,但是她并不属于客户端 程序员所需接口的一部分。因此将方法和域指定成private,对客户端程序员而言是一种服务。因为这样他们可以很清楚地看到什么对他们重要,什么是他们可以忽略的,这简化了他们对类的理解。

 第二,这也是最重要的原因,为了让类库的设计者可以更改类的内部工作方式,而不必担心这样会给客户端程序员造成重大影响。访问权限控制确保不会有任何客户端程序员依赖于某个类的底层实现的任何部分。

4、程序案例分析

public class CleanSer {
	private String s="Cleanser";//private修饰的成员子类可以继承,但不能直接访问
	public void append(String a){
		s+=a;
	}
	public void dilute(){
		append(" dilute()");
	}
	public void scrub(){
		append(" scrub()");
	}
	public String toString(){
		return s;
	}
	public static void main(String[] args) {
		CleanSer cl=new CleanSer();
		cl.dilute();
		cl.scrub();
		printWithbr(cl);
	}


public class Detergent extends CleanSer{
	//重写父类的一个方法
	public void scrub(){
		append("Detergent.scrub()");
		super.scrub();//调用父类版本
	}
	
	//增加一个新方法
	public void foam(){
		append(" foam()");
	}
	
	public static void main(String[] args) {
		Detergent de=new Detergent();
		//de.s="zpc";//无法访问父类private修饰的成员,如将CleanSer类的s修饰符改成public则可以访问
		de.dilute();
		de.scrub();
		de.foam();
		printWithbr(de);
		printWithbr("调用CleanSer的main方法");
		CleanSer.main(args);//在这个类里可以调用另外一个类的静态方法(包括main方法)
	}
}
/*OutPut:
 *Cleanser dilute()Detergent.scrub() scrub() foam()
 *调用CleanSer的main方法
 *Cleanser dilute() scrub()
 */

可以看出Detergent 类确实继承了CleanSer类中的private成员s,只不过在Detergent类中不能显式访问,可以通过父类的public方法间接访问,可以看到输出结果包含了"Cleanser"这个字符串,倘若将CleanSer类的变量s的修饰符改成public则注释掉的那句话不会报错,可以访问de.s,改变s的值。
此时的输出结果是:
zpc dilute()Detergent.scrub() scrub() foam()
调用CleanSer的main方法
Cleanser dilute() scrub()

这种"赤裸裸"地修改从父类继承的成员属性值的方式不是一种好的初始化方式,破坏了封装性,假设某一天你要修改父类,剔除了s属性,那么那些直接访问了s的子类就要受影响,一种好的设计方式是将父类的那些不需要子类知道的成员(包括属性和方法)设成private的,然后提供public的方法对那些成员进行操作,子类只要能访问这些public方法就行了,它不需要知道父类的太多细节。将来修改某个类的实现细节时,只要不改变原来对外提供的public方法,则就不影响使用这个类的类,否则牵一发而动全身。

使用封装思想实现(set、get方法):
public class CleanSer {
	//private String s="Cleanser";//private修饰的成员子类可以继承,但不能直接访问
	public String s=null;
	public String getValue() {
		return s;
	}
	public void setValue(String s) {
		this.s = s;
	}
	public void append(String a){
		s+=a;
	}
	public void dilute(){
		append(" dilute()");
	}
	public void scrub(){
		append(" scrub()");
	}
	public String toString(){
		return s;
	}
	public static void main(String[] args) {
		
		CleanSer cl=new CleanSer();
		cl.setValue("CleanSer");
		cl.dilute();
		cl.scrub();
		printWithbr(cl);
	}


}


public class Detergent extends CleanSer{
	//重写父类的一个方法
	public void scrub(){
		append("Detergent.scrub()");
		super.scrub();//调用父类版本
	}
	
	//增加一个新方法
	public void foam(){
		append(" foam()");
	}
	
	public static void main(String[] args) {
		Detergent de=new Detergent();
		de.setValue("Detergent");
		de.dilute();
		de.scrub();
		de.foam();
		printWithbr(de);
		printWithbr("调用CleanSer的main方法");
		CleanSer.main(args);//在这个类里可以调用另外一个类的静态方法(包括main方法)
	}
}
/*输出
Detergent dilute()Detergent.scrub() scrub() foam()
调用CleanSer的main方法
CleanSer dilute() scrub()
*/


举一个例子说说为什么要封装,布布扣,bubuko.com

举一个例子说说为什么要封装

原文:http://blog.csdn.net/hellozpc/article/details/23345471

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!