5.3.2 实现封装

5.3.2 实现封装

隐藏和封装是面向对象程序设计的特性,那么如何进行数据的隐藏和封装呢?根据封装原则,使用者可以访问类中的部分方法,但不能直接访问成员变量。Java中通过设置类的访问权限和类中成员的访问权限,来实现封装的特性。

Java为对象变量提供了4种访问权限:public,protected,private和friendly。下面分别叙述访问权限修饰符的作用。

1.public

Java中类的访问控制符只有一个:public,即公共的。一个类被声明为公共类,表明它可以被所有的其他类所访问和引用,这里的访问和引用是指这个类作为整体是可见和可使用的,程序的其他部分可以创建这个类的对象、访问这个类内部可见的成员变量和调用它的可见的方法。在程序中可以用import语句引入其他包中的public类。那些被public定义的类中成员变量和方法可以供其他类访问,这些类、方法或成员变量均可以用来供其他类访问。

一个类作为整体对程序的其他部分可见,并不能代表类内的所有属性和方法也同时对程序的其他部分可见,前者只是后者的必要条件,类的属性和方法能否为其他所有类所访问,还要看这些属性和方法自己的访问控制符。

一个源程序文件可以声明多个类,但用public修饰的类只能有一个,且该类名必须与文件名相同,其他类可以是没有修饰符的。

【例5-3】使用import引入已经定义的,属性为public的Employee类,引用其方法。

img152

img153

定义了公共类Employee以及公共成员变量salary和方法displayDetails(),将此文件保存为Employee.java ,编译后生成Employee.class类。

引入Employee类并引用Employee类的方法。

img154

程序运行结果为:

img155

2.private

如果不想让其他类进行访问,采用什么方法呢?可以对其设置private访问权限。

【例5-4】定义时间类的私有变量,如果使用类外的方法来引用此私有变量会产生什么问题呢?

img156

img157

程序编译结果:

img158

1个错误

【程序说明】在此对Time类的 hour,minute,second设置为私有变量,所以在类外不能对其进行访问“time.hour = 11;”。

3.protected

使用protected定义的成员变量或方法具有二重性,类本身、子类或包中的方法可以访问它们,而对于其他类没有访问权限。

关于类的继承、包的概念将在后面介绍。

【例5-5】修改Time类的setTime()和toString()方法的修饰符为 protected,通过创建对象来引用这两个方法。

img159

img160

程序运行结果:

设置时间=11:22:33

【程序说明】对Time类的setTime()和toString()方法设置的protected属性在程序引用中可以像使用public修饰的权限方法一样来引用。

4.friendly

如果没有说明以上任意一种访问说明符,则访问的范围是友好的。一个可以进行友好访问的类、变量、方法对于包中的所有类都是可访问的。(包是类的集合)。

注意:在Java中,友好并不是一个关键字。它是在未指明访问说明符的情况下,用于确定访问级别的一个术语。不能创建一个带有友好说明符的类、变量或方法。

请考虑以下类的集合。类Y 和 Z 是从类X继承下来的。类Z所属的包不同于类X 和Y。如图5-1所示。

img161

图5-1 包与继承的关系

在图5-1中,在类X中定义了方法accessMe()。表5-2展示了类Y和类Z对方法accessMe()的可访问性。

表5-2 类Y和类Z对方法accessMe()的可访问性

img162

【例5-6】使用方法的默认访问权限来引用方法。

img163

img164

程序运行结果如下:

img165

【程序说明】由于类AAA与类BBB在编译后系统自动将它们放在一个包内。对于AAA类中的executing()方法而言,没有进行访问权限设定,则通过“import AAA”语句引入,使得AAA类对象a可以调用executing()方法,即“a.executing();”。但如果在AAA类中对executing()方法加上private访问权限,则当使用a对象调用executing()方法时,编译时会出现错误提示信息,读者可以上机试试。