Java中的访问控制权限

简介

Java中为何要设计访问权限控制机制呢?主要做用有两点:java

(1)为了使用户不要触碰那些他们不应触碰的部分,这些部分对于类内部的操做时必要的,可是它并不属于客户端程序员所需接口的一部分。程序员

(2)为了让类库设计者可用更改类的内部工做方式,而没必要担忧会对用户形成重大影响。函数

 

Java中的访问权限控制的等级,按照权限从大到小依次为spa

Public -> protected -> 包访问权限(没有权限修饰词)-> private设计

 

(package)

Java中包(package)的概念和C++中命名空间(namespace)的概念很相似,均可以限制类的做用域。两者最大的差异在于,Java中的包隐式地指明了类的树形层级结构(同时也是Java源码文件的目录结构)。这样作的好处在于:能够经过文件系统中对于文件路径惟一性的要求来限制类的惟一性。orm

 

代码组织

编写一个Java源代码文件(.java文件)时,此文件一般被称为编译单元。在编译单元内最多容许有一个public类,且该类的名称必须与文件名彻底相同(包括大小写)。继承

编译一个.java文件时,在.java文件中的每一个类都会有一个.class输出文件,这个文件名和类名是相同的。Java可运行程序是一组能够打包并压缩为一个Java文档文件(JAR包,使用Javajar文档生成器).class文件。Java解释器负责这些文件的查找、装载和解释。接口

类库其实是一组类文件。其中每一个.java文件最多容许有一个public类,以及任意数量的非public类。所以,每一个文件都有一个构件。若是要将这些构件(每一个构建有一个.java文件和若干个.class文件)组织起来,造成不一样的群组,可使用Java中的关键字packageci

 

(package)的做用

(1)     把功能类似或相关的类或接口组织在同一个包中,方便类的查找和使用。element

(2)     如同文件夹同样,包也采用了树形目录的存储方式。同一个包中的类名字是不一样的,不一样的包中的类的名字是能够相同的,当同时调用两个不一样包中相同类名的类时,应该加上包名加以区别。所以,包能够避免名字冲突。

(3)     包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

 

建立包

Java中,使用package关键字来指定代码所属的包(命名空间)。

语法格式:

package pkg1[pkg2[pkg3…]];

注意点:

(1)     包的名字隐含地指出了代码的目录结构。

(2)     同一目录下的public类名(同时也是java文件名)应该是独一无二的。

(3)     包声明应该在源文件的第一行,每一个源文件只能有一个包声明,这个文件中的每一个类型都应用于它。

(4)     若是一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中。

(5)     package的名字通常全是小写字母。

例如:

查看java.util.ArrayList类的源码能够看到文件第一行代码为:

package java.util;

它的代码目录结构就是java/util/ArrayList.java

 

导入包

Java中,使用import关键字来导入包。

语法格式:

import package1[.package2…].(classname|*);

例:

仍是以java.util.ArrayList来举例。若是以一个了类完整路径的方式来使用它,十分不方便。

java.util.ArrayList<String> list = new java.util.ArrayList<String>();

若是想要省略前面的路径,可使用import关键字。

import java.util.ArrayList;

文件中使用了import导入包后,前面的声明list的代码就能够简化以下:

ArrayList<String> list = new ArrayList<String>();

 

 

访问权限修饰词

package:包访问权限

若是不提供任何访问权限修饰词,则意味着它是包访问权限

默认访问权限没有任何关键字,但一般是指包访问权限(有时也表示为friendly,有点像C++中的友元概念)。这意味着包中全部其余类均可以访问这个成员或方法,可是这个包以外的全部类不能够访问

例:

com.notes.packages.test.Info

package com.notes.packages.test;

publicclass Info {

    void print() { System.out.println("default method -- print()"); }

}

 

com.notes.packages.test.PublicDemo01

package com.notes.packages.test;

publicclass PublicDemo01 {

    publicstaticvoid main(String[] args) {

        Info x = new Info();

        x.print();

    }

}

PublicDemo01Info在同一个包下,能够访问Infodefault级别的方法——print()

 

com.notes.packages.PublicDemo02

package com.notes.packages;

import com.notes.packages.test.Info;

publicclass PublicDemo02 {

    publicstaticvoid main(String[] args) {

        Info x = new Info();

        // x.print(); // Error

    }

}

PublicDemo02Info不在一个包下,不能够访问Info包访问权限级别的方法——print()

 

public:接口访问权限

使用public关键字,就意味着被声明的成员或方法对全部人都是能够访问的

例:若是将default级别权限例子中的print()方法权限设为public,则PublicDemo02能够访问。

package com.notes.packages.test;

publicclass Info {

    publicvoid print() { System.out.println("public method -- print()"); }

}

 

private:没法访问

使用private关键字,就意味着被声明的成员或方法,除了本类,其余任何类都没法访问

应用场景:单例模式

 

protected:继承访问权限

新类(称之子类或派生类)经过继承能够复用一个现有类(称之父类或基类),而后扩展基类的成员、方法。有时,基类的建立者会但愿某个特定成员,将它的访问权限赋予派生类而不是全部类。public没法作到这一点,为此,引入了protected来完成这一工做。protected也提供包访问权限,也就是说,派生类以及相同包内的其余类均可以访问protected成员或方法

例:子类继承父类后,能够访问父类的protected成员。

class Father {

    private String a = "private";

    protected String b = "protected";

    public String c = "public";

};

 

class Son extends Father {

    publicvoid print() {

        // System.out.println("element a" + super.a); // Error

        System.out.println("element b" + super.b);

        System.out.println("element c" + super.c);

    }

}

 

publicclass ProtectedDemo01 {

    publicstaticvoid main(String args[]) {

        Son sub = new Son();

        sub.print();

    }

};

 

访问权限修饰词的注意点

前面各个例子中展现了类的成员、方法均可以用各类权限修饰词来修饰。

除此以外,还有一些须要注意的点:

(1)     静态成员、静态方法的权限修饰词的用法和普通成员、方法同样。

(2)     类虽然也能够被修饰词修饰,可是不能够用privateprotected两个权限修辞词。

(3)     有些书中将包访问权限又叫作默认访问权限。我的不建议这么去记,由于这很容易与Java Se8中新特性——default关键字混淆。这个关键字只能用于Interface,做用是容许程序员在Interface中定义接口的默认具体实现(以往的JDK版本是不容许这样的,你只能在接口中声明方法)。

相关文章
相关标签/搜索