Java关于访问权限的关键字有三个:private、protected以及public,同时Java还有一个默认的访问权限——包权限,所以Java总共有四种访问权限控制。
public和private没什么好说的,public允许在所有地方访问,而private只能在本类以及内部类中进行访问。
容易混淆的是protected和默认的访问权限,时间长了就不太容易表述两者的差别,下面通过一个例子来说明这两者的差别。
基类位于包main.access下,代码如下:
package main.access;
public class BaseClass {
protected void protectedMethod() {
System.out.println("protected method");
}
void defaultMethod() {
System.out.println("default method");
}
}
在包main.access下还有一个子类SamePackage和非子类SamePackage,代码如下:
package main.access;
public class SamePackage extends BaseClass{
public void foo() {
protectedMethod();
defaultMethod();
}
public static void main(String args[]) {
BaseClass baseClass = new BaseClass();
baseClass.protectedMethod();
baseClass.defaultMethod();
}
}
package main.access;
public class SamePackage {
public static void main(String args[]) {
BaseClass baseClass = new BaseClass();
baseClass.protectedMethod();
baseClass.defaultMethod();
}
}
在另一个包test.access中有一个类DiferentPackage
package test.access;
import main.access.BaseClass;
public class DiferentPackage extends BaseClass {
public void foo() {
protectedMethod();
defaultMethod(); // error
}
public static void main(String[] args) {
BaseClass baseClass = new BaseClass();
baseClass.protectedMethod(); //error
baseClass.defaultMethod(); //error
}
}
在main.access的子包main.access.sub下还有一个类SubPackage,其代码如下:
package main.access.sub;
import main.access.BaseClass;
public class SubPackage extends BaseClass {
public void foo() {
protectedMethod();
defaultMethod(); // error
}
public static void main(String args[]) {
BaseClass baseClass = new BaseClass();
baseClass.protectedMethod(); // error
baseClass.defaultMethod(); // error
}
}
结论:在包相同的类中,protected和默认的访问权限均可见,无论子类或者非子类;包不相同时,protected在子类中可见,而默认的访问权限在子类中不可见。
默认的接口访问权限是什么?
public interface InterfaceAccess {
void foo();
}
是和类一样的默认访问权限吗?来看看字节码吧
Compiled from "InterfaceAccess.java"
public interface main.access.InterfaceAccess {
public abstract void foo();
}
字节码中已经使用public abstract替代,所以“默认”(不写)在接口中是public,而不是我们通常理解的包访问权限,它不同于类的字节码,
Compiled from "BaseClass.java"
public class main.access.BaseClass {
public main.access.BaseClass();
protected void protectedMethod();
void defaultMethod();
}
所以写接口的时候不要“画蛇添足”地增加访问修饰符,编译器会帮我们做好增加修饰符的工作。
总结
来个图
画出图来之后就挺好记的。
关于访问修饰符使用的tips
1、访问修饰符尽可能从严使用,能用private就不要用protected,能用protected就不要用public;
2、接口一般不要使用访问修饰符;
3、待你们来续...