Java访问权限修饰词
如果不提供任何访问权限修饰词,则意味着它是“包访问权限”,因此,无论如何所有事物都具有某种形式的访问权限控制。
java的访问权限共分为四种:public、protected、private、包访问权限(也就是不使用修饰词默认的),通过学习,下面来具体认识:
(1)包访问权限
包访问权限也就是没有关键字的默认访问权限,作用是:对于当前包中的所有其他类都可以访问这个成员,而对于这个包以外的类,都是private的。
因此取得对某成员访问的几种途径是:
- 使该成员成为public.
- 通过不加访问修饰词并其将其他类放置于同一个包内.
- 提供public的get/set方法,以读取和改变数值,这也是JavaBeans的基本原理。
(2)public:接口访问权限
2.1先看一个常规的情况public的访问:
package me.funnyzhao.util;
public class Cookie {
public Cookie(){
System.out.println("Cookie");
}
//包访问权限
void bite(){
System.out.println("bite");
}
//继承类访问权限
protected void bite2(){
System.out.println("bite2");
}
//私有的,只能在类内部调用
private void bite3(){
System.out.println("bite3");
}
//公共的,其他类(不同包/同包)可以访问
public void bite4(){
System.out.println("bite4");
}
}
现在在另一个包下创建Cookie对象:
package me.funnyzhao.main;
import me.funnyzhao.util.Cookie;
public class TestDo {
public static void main(String[] args) {
Cookie co=new Cookie();
co.bite4();
// !co.bite();
// !co.bite2();
// !co.bite3();
}
}
除了bite4()方法可以访问,其余都是不可以的,如果强制使用,编译器会打印以下错误:
2.2再看一个特殊的情况【默认包】:
令人吃惊的是,下面的程序代码虽然看起来破坏了上述规则,但它任然可以编译
class Cake {
public static void main(String[] args) {
Pie x=new Pie();
x.f();
}
}
/*输出:
f
*/
Pie类
class Pie {
void f(){
System.out.println("f");
}
}
按理说Pie和f()享有包访问权限,Cake是不可以访问他们的,因为它们也没有用public修饰。但是为什么为编译通过呢? 下面来一步步揭开谜底:
1.首先,Pie类和f()的确享有包访问权限,这是正确的,但只是部分正确。
2.观察右图:
可以发现,Cake和Pie处于相同的目录层级&&它们都没有给自己设定任何包的名称,而java会把这样的文件自动看作是隶属于该目录的默认包之中,于是它们为该目录中的其他类都提供了包访问权限。
(3)private:你无法访问
关键字private的意思是:除了包含该成员的类之外,其他任何类都无法访问这个成员。所以,private允许我们随意改变该成员,而不必考虑这样做是否会影响到包内的其他类。
然而private的灵活使用对程度构建的帮助作用是很大的,下面上代码:
示例1:
class Sundae{
private Sundae(){}
static Sundae makeASundae(){
return new Sundae();
}
}
public class TestDo{
public static void main(String[] args){
// !Sundae x=new Sundae();
Sundae x=Sundae.makeASundae();
}
}
这是一个说明private终有其用物之地的示例:可能想控制如何创建对象,并阻止别人直接访问某个特定的构造器(或全部构造器)。
一般在实际开发中,private用来“封装“一些实现细节,防止不必要的改动。
(4)protected:继承访问权限
有时,基类的创建者会希望有某个特定成员,把对它的访问权限赋予子类而不是其他/所有类,这就需要protected来完成这一工作。protected也提供包访问权限,也就是说,相同包内的其他类可以访问protected元素。
看下面这个程序:
package me.funnyzhao.util;
public class Cookie {
public Cookie(){
System.out.println("Cookie");
}
void bite(){
System.out.println("bite");
}
}
有一个其他包中的类继承类Cookie:
package me.funnyzhao.other;
import me.funnyzhao.util.Cookie;
public class Chip extends Cookie {
public Chip(){}
public void chomp(){
//! bite();
}
public static void main(String[] args){
Chip x=new Chip();
x.chomp();
}
}
我们发现,Chip类中是不能访问Cookie的bite()方法的,尽管是继承。因为bite()方法是包访问权限的,除非给它public修饰,但这样,除了Cookie的子类可以访问,其他类也都可以访问了,因而不是好的解决方案。但是protected就可以实现我们想要的效果:
package me.funnyzhao.util;
public class Cookie {
public Cookie(){
System.out.println("Cookie");
}
//加上protected修饰
protected void bite(){
System.out.println("bite");
}
}
现在其他包中继承Cookie的类就可以访问bite()了:
package me.funnyzhao.other;
import me.funnyzhao.util.Cookie;
public class Chip2 extends Cookie {
public Chip2(){}
public void chomp(){
bite();
}
public static void main(String[] args){
Chip2 x=new Chip2();
x.chomp();
}
}
声明:文中“>“(引用部分均为《java编程思想》一书的语句),此处用作学习笔记,特此感谢java的前辈们。