你真的了解Java中的访问权限控制么

今天我们来讨论一下Java中的访问权限控制——Java中的访问权限控制是为了确定类库的边界而设计的一种机制。

这个机制起到了两个作用:首先,为了让客户端程序员不能接触他们不该接触的部分;其次,为了让类库设计者可以更改类的内部工作方式,而不必担心会对客户端程序员产生影响。

下面我们先分别讨论一下每种访问权限控制,然后再说一下访问权限控制能够被用在什么场合。

一、分别讨论一下每种访问权限控制:

Java中的访问权限一共有四种:public、protected、friendly(包访问权限)、private。可以作用在基本类、抽象类、接口、内部基本类、内部抽象类、内部接口及它们的属性和方法上。

1.public:接口访问权限。表示明确公开给客户端程序员使用的。

2.protected:继承访问权限。处理的是继承的概念,需要注意的是Java中的继承关系不会引起任何访问权限控制的改变,即父类中为protected的方法在子类中也是protected的。另外,protected也提供包访问权限。

3.friendly:包访问权限。也是Java默认的访问权限控制。需要注意的是Java中的“同一个包下”必须是同一级包才行,也就是说如果一个二级包B位于一个一级包A下,那么,B中的friendly类在A中也是看不到的。另外,父类包访问权限修饰的能不能通过子类看到,仅仅看调用方跟是否和父类位于同一个包下有关,而与调用方是不是和子类位于同一个包下没有关系。

4.private:私有访问权限。仅供本类内部使用。

总之,一个方法或属性能不能被调用方看到,仅仅和调用方与最初定义这个方法或属性的类的关系有关,而与其他都无关。

二、访问权限控制能够被用在什么场合:

1.基本类、抽象类、接口的访问权限:只能是public或default。因为private指的是只有自身可见。对于基本类、抽象类、接口来说如果定义为private则除自身外的任何类都不可见,那这个类的定义就没有任何意义了。所以不能是private。而protected是为继承过程中类的属性和方法的访问权限控制变动而设的,对于类来说没有意义,所以也不能是protected。

2.内部基本类、内部抽象类、内部接口的访问权限:注:因为局部内部类和匿名内部类不能有访问修饰符(以及static修饰符),所以这里讨论的内部基本类、内部抽象类、内部接口都是指成员内部类或静态内部类。类中的内部基本类、内部抽象类、内部接口可以拥有public、protected、default、private四种访问权限。接口中的内部基本类、内部抽象类、内部接口只能是public访问权限(如果不写访问修饰符,默认也是public,写了反而是多余的)。(稍后在三.3中讨论)可见,无论是类还是接口中的(成员/静态)内部类的访问权限都与其普通属性具有的访问权限相同。需要注意的是:

1).当实现某个接口时,并不需要实现嵌套在其内部的任何内部接口。2).private修饰的内部接口不可以在定义它的类之外被实现。3).private修饰的内部接口的实现类(继承于它的接口)可以是public修饰的。但是从定义它的类之外来看,被public修饰的实现类(继承于它的接口)不允许向上转型。

3.基本类、抽象类、接口的属性和方法的访问权限:1).对于基本类:所有的属性和方法都可以被public、protected、default、private四种访问权限修饰。2).对于抽象类:a.属性和基本方法都可以被public、protected、default、private四种访问权限修饰。b.抽象方法可以被public、protected、default三种访问权限修饰。因为private修饰的抽象方法子类看不到,自己又没法用,所以当然不能有private修饰的抽象方法啦。3).对于接口:无论是属性还是方法,都只能被public修饰。

需要记住:接口是最高层次的抽象,是一种协议,所有在接口中出现的都必须是明确的、标准性的。

原因:private就不说了,因为定义为private对接口来说没有任何意义(接口没有实现,所以没有办法自己用自己)。对于friendly和protected也是不可以的,因为这样的话实现了它的子类的属性和方法也可以是friendly和protected,但是这样就可能存在一种情况:一些本应能正常访问这些属性和方法的类(但与实现类不在同一个包下),却无法访问,而接口并不知道未来会被哪个类调用,所以尽量放宽接口的访问权限控制,就设置为public。另外需要注意的是:

a.接口中的成员变量为什么要用final修饰?

接口是最高层次的抽象,是一种协议,协议是所有实现接口的类都必须遵守的。如果属性不被final修饰,那么实现接口的类就可以更改这个变量的值,那么这个属性就不应在接口中出现(可以放到抽象类中)。例如考虑将ATM机抽象为接口,那么读卡口的尺寸这个属性必须固定,不然所有的具体实现类都可以随意更改,也就失去了定义它的意义了。总之:凡是在接口中定义的都不能被修改,凡是可以被修改的都不应在接口中出现。

b.接口中的成员变量为什么要用static修饰?这个问题跟java中一个类可以实现多个接口有关,我们假设有两个接口A和B,而类C实现了接口A和B。假设,此时,A和B中都有一个变量N,如果N不是static类型的,那么在C中该如何区分N到底是A的还是B的呢?而,如果是static类型的,我们可以通过A.N和B.N来区别调用A或者B中的成员变量N。

参考资料:

1.Java接口中的成员变量为什么必须声明为publicstaticfinal?









































白斑病医院
白癜风土方治疗



转载请注明:http://www.jiaju1314.com/jyqj/9698.html