访问修饰符
在Java类中,属性也称为成员变量或实例变量,其声明语法如下:
<访问修饰符> <数据类型> <属性名>;
访问修饰符用于控制属性的可见性和访问范围,也就是Java中的访问权限。
- private:只能在同一个类中访问。
- default(默认权限、不写修饰符):可以在同一个包内访问。
- protected:可以在同一个包内或子类中访问。
- public:可以从任何地方访问。
同一个类中 | 同一个包中 | 不同包的子类 | 不同包的无关类 | |
---|---|---|---|---|
public | ✔ | ✔ | ✔ | ✔ |
protected | ✔ | ✔ | ✔ | |
无(空着不写) | ✔ | ✔ | ||
private | ✔ |
private
private表示类的私有属性,只能在类自身中访问
如图,我们在Person类中定义了一个私有属性name,在实例化的对象中访问时,会报错
default
当我们不写修饰符,即不设定任何权限时,JVM会提供默认权限,即包权限。
public class Auth {
public static void main(String[] args) {
// TODO 面向对象 - 访问权限
Person people = new Person();
System.out.println(people.name);
}
}
class Person {
String name = "shixiaoshi";
}
上述代码中,我们在Person类中定义了name属性,并没有指明权限属性,这个时候它就是默认权限,可以在这个包文件内任意地方访问。
我们在看一个例子,我们定义一个Object2的包,包内的Auth方法中定义一个name属性,他是默认权限。
然后,我们在Object1的包内访问这个name属性
由于name属性是包权限,所以当我们跨包的时候,就无法访问到了。
protected
public
public是公共的访问权限修饰符,在任何地方都可以用。
公共类的唯一性
如下图,当我们在同一个java源码中写第二个public时,代码就会报错。
类名与文件名一致性
公共类的文件名必须与源码文件名相同
如下图,源码文件名为Auth,当我们把类名改成Auth1时,代码就会报错
main方法的public
main方法的public是不能删除的。如下图,删除public后,main方法就无法执行了
main方法是有JVM调用的,JVM调用时,应该可以任意调用,而不用考虑权限问题。
main方法的static表示其是Auth类的自身的静态成员,也不能删除(方便JVM虚拟机执行)。
Java中的内部类与外部类
简述
在Java类中,属性可以通过访问修饰符来控制访问权限,访问修饰符有四种
- private:只能在同一个类中访问。
- default:(什么都不写)可以在同一个包内访问。
- protected:可以在同一个包内或子类中访问。
- public:可以从任何地方访问。
比如,下面的Auth类中就有一个私有属性name
public class Auth {
private String name ="shixiaoshi";
public static void main(String[] args) {
}
}
那Auth类本身可以用这四种修饰符修饰吗?要解决这个问题,我们需要先了解一下什么是内部类,什么是外部类。
观察下面代码
package Object;
public class Auth {
private String name ="shixiaoshi";
public static void main(String[] args) {
}
}
class People {
public class InnerClass {
}
}
- 在源码中(即Object包内)直接声明的类就是外部类,如 Auth、People
- 在类中声明的类就是内部类,如InnerClass
外部类的修饰符
如图,我们定义了四个类,分别加上了不同修饰符
根据编译器的报错结果可知,Java不允许外部类使用private和protected修饰符
内部类的访问
public class People {
OuterClass outer = new OuterClass();
// 内部类可以看做外部类的属性
OuterClass.InnerClass innerClass = outer.new InnerClass();
}
class OuterClass {
// 内部类
public class InnerClass{
}
}
内部类可以看做外部类的一个属性,因此可以使用所有修饰符。上述代码中,通过OuterClass outer = new OuterClass();创建了OuterClass类的实例,通过outer.new InnerClass()实例化了内部类。OuterClass.InnerClass指明了innerClass的数据类型。
单例模式
类的构造函数也是支持访问修饰符的。如protected权限
public class People {
public static void main(String[] args) {
Dog ww = new Dog();
}
}
class Dog {
protected Dog(){
System.out.println("汪汪");
}
}
public权限
public class People {
public static void main(String[] args) {
Dog ww = new Dog();
}
}
class Dog {
public Dog(){
System.out.println("汪汪");
}
}
JVM默认提供给类的构造方法,其实就是公共的,无参的构造方法。
但是,直接使用private权限时,就会报错
那么,什么时候private权限是在什么使用呢?
1、类的创建过程复杂(禁止外部类使用)
2、实现单例模式
public class People {
public static void main(String[] args) {
Dog ww = Dog.getInstance();
}
}
class Dog {
private static Dog dog = null;
private Dog(){
System.out.println("汪汪");
}
public static Dog getInstance(){
if(dog == null){
dog = new Dog();
}
return dog;
}
}