菜鸟笔记 -- Chapter 6.2.1 权限修饰符
6.2.1 权限修饰符
面向对象的三大特性就有封装,封装隐藏了对象的属性和实现细节,仅对外提供公共访问方式,而这个访问方式就是由权限修饰符控制的。Java中的权限修饰符主要包括private、public、protected和默认(default),及一些其他权限修饰符,这些修饰符控制着对类和类的变量及函数的访问,下面我们来看一下具体的访问权限:
|
类 |
修 |
饰 |
符 |
private |
protected |
public |
default |
|
本类 |
可见 |
可见 |
可见 |
可见 |
同包其他类或子类 |
不可见 |
可见 |
可见 |
可见 |
其他包的类或子类 |
不可见 |
不可见 |
可见 |
不可见 |
package cn.yourick.permissionmodifier; import judge.object.Test; public class PermissionTest extends ModifierTest{ public static void main(String[] args) { PermissionTest permissionTest = new PermissionTest(); permissionTest.test(); PermissionTestDemo.ii = 90; System.out.println(PermissionTestDemo.ii); } //只能访问非私有的函数 public void test(){ PermissionDemo demo = new PermissionDemo(); demo.test2();; } final public static class PermissionTestDemo{ static int ii = 89; protected void test(){ System.out.println("static只能用于类只能是内部类!"); } } @Override public void test6() { super.test6(); } }
package cn.yourick.permissionmodifier; class PermissionDemo { public static void main(String[] args) { /** * private只能被自己使用,哪怕是内部类,也是只能被内部类自己使用, * 私有类不能被其他类实例化[提示不能实例化],私有静态类可以 * 私有静态类只能被自己的外部类实例化,不能被除了这个外部类意外的其它类实例化 */ PermissionDemoTest demoTest = new PermissionDemoTest(); demoTest.fun(); String name = PermissionDemoTest.test();//静态私有类调用静态函数, System.out.println(name); //protected的使用 ModifierTest.ModifierTestDemo demo = new ModifierTest().new ModifierTestDemo(); System.out.println("访问protected的成员字段:"+demo.ii); demo.test(); } private static class PermissionDemoTest{ /**如果私有函数中存在静态,那么类也应该被声明静态,否则报出下面错误 * The method main cannot be declared static; * static methods can only be declared in a static or top level type * 这句话的意思是,静态函数只能被应用于静态类或者是在一个顶级类[外部类中,外部类不能被声明private,自然也就能够通过类名调用] * @param args */ public static void main(String[] args) { System.out.println("私有化函数中如果存在静态的话,那么类也要被声明为静态!"); } private void fun() { System.out.println("私有只能应用于内部类或方法及字段,不能应用于外部类!"); } private static String test() { return "name"; } } private String test() { return "username"; } void test2(){ System.out.println("方法可以没有修饰符,即默认修饰符!"); } }
package cn.yourick.permissionmodifier; class ModifierTest{ protected class ModifierTestDemo extends PermissionTest{ // static int i = 90;如果内部类中有静态,那么这个内部类是一定要背声明为静态的,不在于这个内部类被怎么修饰 protected int ii = 90; //重写了方法 public void test(){ System.out.println("事实证明,类的继承不受限与权限修饰符的等级,但肯定不能继承私有了!"); System.out.println("事实也证明权限修饰符不约束他的其它类元素!"); } protected void fun(){ System.out.println("外部类只能被修饰为public和default!"); } } public void test6(){ System.out.println("default类,能被继承!"); } }
解读:
- 外部类只能被声明为public和default,只有内部类可以被声明为private和protected;
- 不可见的理解是看不到这个类,更不用说继承和实例化对象了。举例A包中有一个default的类AA,那么在B中是看不到这个类的,既不能继承,也不能实例化。
- 当声明类时不使用public、protected和private修饰符设置类的权限,则这个类为默认访问权限。
- 类的权限设定会约束类成员的权限设定(即假如类修饰protected,方法修饰符是public,那么类的权限会约束方法的权限到protected)。因为程序的最小单元是类,所以访问的权限首先由类决定,然后才是方法。
- Default修饰的类不能被外包访问,只能在本包使用,可以被本包其它类继承。Default只是形容一个类的修饰符,它并不是一个实际存在的修饰符,我们反编译一个默认修饰符的类发现,并没有添加什么标识:下面是反编译PermissionDemo类后的情形,并没有什么标识符
class PermissionDemo
Java语言的权限除了上面四种外还有下面几种常见的,我们一一介绍:
- abstract修饰符:abstract(抽象)修饰符,可以修饰类和方法。abstract修饰符会使这个类成为一个抽象类,抽象类不能生成对象实例,可以包含抽象方法,抽象方法没有具体功能,只能衍生子类。abstract和private ,abstract和final ,abstract和static一起用是没有意义的,会导致编译错误;【abstract 的东西是还没实现的,用处是让子类去实现。而 final 会禁止子类修改,如果加上 final 则子类无法去实现,所以 final 不能与 abstract 共存。private 同理,private 的东西子类看不到,自然无法去实现它。static.被abstract修饰的方法没有方法体,被static修饰,可以用类名点调用,但是类名点调用抽象方法是没有意义的.】
- final修饰符:Java关键字final有“这是无法改变”或者“终态的”含义,它可以修饰非抽象类,非抽象类成员方法和变量,final类不能被继承,没有子类,final类中的方法默认是final的,final方法不能被子类的方法重写,但可以被继承,final成员变量表示常量,只能被赋值一次,赋值后值不再改变【一经声明必须赋值】。final不能用于修饰构造方法。Final类中的成员字段是可以被改变的。final修饰引用类型时,该引用类型不能被重新指向其他引用;private类型的方法都默认是final方法,因此也不能被子类重写;私有的不能被其他类访问,就不存在被继承的问题;
- static修饰符:static是一个修饰符,用于修饰成员(常量、成员变量、成员方法),也可以形成静态代码块。Static用来修饰类,只能修饰静态类。static用来修饰方法和变量,代表静态,如果声明了静态,那么是随着类的加载是被单独放在方法区,因为方法区是一个数据共享区,不管什么变量访问它,都是同一份。静态可以通过类名调用来访问,也可以通过对象来调用,但我们一般不通过对象,那样会造成内存浪费;静态方法中不能直接访问非静态的方法和变量,如果要访问,通过对象调用,非静态方法可以直接访问静态和非静态成员,静态方法中不能使用this和super关键字,静态方法不能被abstract修饰,静态方法和变量可以通过类名调用访问,非静态只能通过对象调用。类被加载时,静态代码块只能被执行一次。类中不同的静态方法代码块按他们在类中出现的顺序被依次执行。
当多个修饰符连用时,修饰符的顺序可以颠倒,不过作为普遍遵守的编码规范,通常把访问控制修饰符放在首位,其次是 static 或 abstact 修饰符,接着就是其他的修饰符