java访问控制符详解

使用访问控制符

java提供了3个访问控制符:private、protected和public,分别代表3个访问控制级别,另外还有一个不加任何访问控制符的访问控制级别,提供了4个访问控制级别。

访问权限由小到大:private——>default——>protected——>public
注意没有default这个关键字,不写则默认代表此访问权限

private(当前类访问权限)

如果类里的一个成员(包括Field、方法和构造器等)使用private访问控制符来修饰,则这个成员只能在当前类的内部被访问。很显然,这个访问控制符用于修饰Field最合适,使用它来修饰Field就可以把Field隐藏在该类的内部。

这个概念大家应该没什么异议

default(包访问权限)

如果类里的一个成员(包括Field、方法和构造器等)或者一个外部类不使用任何控制符修饰,我们就称它是包访问权限,default访问控制的成员或外部类可以被相同包下的其他类访问。

何为包 package
java引入了包(package)机制,提供了类的多层命名空间,用于解决类的命名冲突、类文件管理等问题。

java规定:位于包中的类,在文件系统中也必须有与包名层次相同的目录结构
假设某个应用中包含两个Hello类,java通过引入包机制来区分两个不同的Hello类。不仅如此,这两个Hello类还对应两个Hello.class文件,它们在文件系统中也必须分开存放才不会引起冲突。

所以java的包机制需要两个方面保证:
1.源文件里使用package语句指定包名;
2.class文件必须放在对应的路径下。

package语句必须作为源文件的第一条非注释性语句,一个源文件只能指定一个包,即只能包含一条package语句,该源文件中可以定义多个类,则这些类将全部位于该包下

java默认为所有源文件导入java.lang包下的所有类,因此在java程序中使用String、System类时都无须使用import语句来导入这些类

也就是说java中要使用其他包中类时需要导入对应类的包或者指定该类的全限定名,如果是在同一包下则可以直接使用同一包下的类

再回到default包访问权限问题上,就拿class来说
先在com.sunrise.eHealth.day0521.other包下定义一个HelloWorld 类,该类的权限为default

package com.sunrise.eHealth.day0521.other;

class HelloWorld {
}

在这里插入图片描述
在com.sunrise.eHealth.day0521包下Demo1类中引入HelloWorld,发现导入了HelloWorld 类所在包,仍然报错,即验证了default权限的类不能在其它包中使用

package com.sunrise.eHealth.day0521.other;

public class Dog {

    public static void main(String[] args) {
        HelloWorld hw = new HelloWorld();
    }

}

在相同包下则可以使用HelloWorld类,并且不用import相应包

protected(子类访问权限)

如果一个成员(包括Field、方法和构造器等)使用protected访问控制符修饰,那么这个成员既可以被同一个包中的其他类访问,也可以被不同包中的子类访问。在通常情况下,如果使用protected来修饰一个方法,通常是希望其子类来重写这个方法。

package com.sunrise.eHealth.day0521.other;

public class Animal {

    protected void info(){
        System.out.println("i am animal");
    }

}

由于外部类的访问控制符只能是public 或者 default(不加访问控制符),不能使用private和protected修饰,因为外部类没有处于任何类的内部,也就没有所在类的内部、所在类的子类两个范围,所以上面代码在方法前加上protected访问控制符,在相同包下调用info方法显然是没有问题的,但是在其它包下则无法调用info方法
在这里插入图片描述
除非该类继承Animal,然后通过子类去访问info方法

public class Demo2 {

    public static void main(String[] args) {
        Monkey m = new Monkey();
        m.eat();

    }

}

class Monkey extends Animal{

    public void eat(){
        this.info();
    }

}

有此可以看出Monkey 子类可以访问info方法,通常情况下,如果使用protected来修饰一个方法,通常是希望其子类来重写这个方法。
有人可能要说希望子类重写何不将父类方法定义为abstract抽象方法呢?
方法定义为abstract是强制让子类重写,而且父类变为抽象类或者接口,不能直接使用父类,也限制了子类必须要重写该方法,只能说侧重点不一样吧

public(公共访问权限)

这是一个最宽松的访问控制级别,如果一个成员(包括Field、方法和构造器)或者一个外部类使用public访问控制符修饰,那么这个成员或外部类就可以被所有类访问,不管访问类和被访问类是否处于同一个包中,是否具有父子关系。

注意:

要使用不同包下的类,必须要先import该类所在包(不导入包则要写全限定名),然后再看访问控制权限,如果是public修饰的类则可以访问,如果是default即没有public修饰的类则不可以访问(即使已经导入了该类所在包)

附上访问控制级别图

在这里插入图片描述

如果一个java源文件里定义的所有类都没有使用public修饰,则这个java源文件的文件名可以是一切合法的文件名;但如果一个java源文件里定义了一个public修饰的类,则这个源文件的文件名必须与public修饰的类的类名相同

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章