Java修饰符
在我们Java语句中通常在最开始就可以看到public static这样的语句,那么他们到底有什么用尼,有哪几种,在什么情况下会用到呢?
首先Java 修饰符分为两类:
- 访问修饰符
- 非访问修饰符
访问修饰符
访问修饰符用来保护对类、变量、方法和构造方法的访问。
一共有四种:
-
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
-
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
-
public : 对所有类可见。使用对象:类、接口、变量、方法
-
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
修饰符 | 当前类(我自己) | 同一包内(我邻居) | 子孙类(同一包) (我儿子) | 子孙类(不同包)(邻居家儿子) | 其他包(陌生人) |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
Y表示允许访问,N表示不允许访问。
非访问修饰符
为了实现一些其他的功能,Java 也提供了许多非访问修饰符。
-
static 修饰符,用来修饰类方法和类变量。
-
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
-
abstract 修饰符,用来创建抽象类和抽象方法。
static举例理解
package demo;
学生类: 姓名 年龄 学号 所在班级
学生对象1: 小王 12 001 101
学生对象2: 小红 13 002 101
学生对象3: 小李 14 003 101
那么他们所在同一班的话,如果要更改教室,就得改三次,浪费了内存。
所以把所在班级这一项只在类中保存独一份,所有本类对象共享同一个数据。
static关键字就是用来修饰这样的,一旦成员变量用了static关键字,这样的内容就不属于对象了,适应于本类了。
* */
public class Demo01Static {
public static void main(String[] args) {
Student str1 = new Student("小王",15);
str1.room = 101;
System.out.println("姓名:" + str1.getName() + "年龄:" + str1.getAge()
+ "学号:" + str1.getId() + "班级是:" + str1.room);
Student str2 = new Student("小红",14);
System.out.println("姓名:" + str2.getName() + "年龄:" + str2.getAge()
+ "学号:" + str2.getId() + "班级是:" + str2.room);
}
}
static修饰符特点
package demo;
一旦使用static修饰成员方法,那么这就成为了静态方法。静态方法不属于对象,而是属于类
* 如果没有static关键字,那么必须首先创建对象,然后通过对象才能使用它
* 如果有了static关键字,那么不需要创建对象,直接通过类名称调用
* 无论是成员变量,还是成员方法,有了static,都推荐使用类名称进行调用
* 静态变量: 类名.静态变量
* 静态方法: 类名.静态方法();
* 注意事项:
* 1.静态只能直接访问静态,不能直接访问非静态
* 原因:因为在内存中先有静态内容,后有非静态内容
* 2.静态方法中不能用this
* 原因:this代表当前对象,通过谁调用的方法,谁就是对象,static中与对象无关*/
public class Demo02StaticMethod {
public static void main(String[] args) {
MyClass obj = new MyClass();//首先创建对象
//然后才能使用没有static关键字的内容
obj.method();
//对于静态方法来说,可以通过对象名进行使用,也可以直接通过类名来直接调用
obj.methodStatic();//不推荐
MyClass.methodStatic();//推荐
}
}
package demo;
public class MyClass {
//成员变量
public String str;
//静态变量
public static String str1;
//成员方法
public void method(){
System.out.println("简单的成员方法");
//成员方法可以访问成员变量与静态变量
System.out.println(str);
System.out.println(str1);
}
//静态方法
public static void methodStatic(){
System.out.println("简单的静态方法");
//静态方法只能访问静态变量
System.out.println(str1);
//System.out.println(str);
}
}
私有访问修饰符-private
私有访问修饰符是最严格的访问级别,所以被声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。
声明为私有访问类型的变量只能通过类中公共的 getter 方法被外部类访问。
Private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。
下面的类使用了私有访问修饰符:
public class Logger {
private String format;
public String getFormat() {
return this.format;
}
public void setFormat(String format) {
this.format = format;
}
}
实例中,Logger 类中的 format 变量为私有变量,所以其他类不能直接得到和设置该变量的值。为了使其他类能够操作该变量,定义了两个 public 方法:getFormat() (返回 format的值)和 setFormat(String)(设置 format 的值)
公有访问修饰符-public
被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public 类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。
以下函数使用了公有访问控制:
public static void main(String[] arguments) {
// ...
}
Java 程序的 main() 方法必须设置成公有的,否则,Java 解释器将不能运行该类。
受保护的访问修饰符-protected
protected 需要从以下两个点来分析说明:
子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
protected 可以修饰数据成员,构造方法,方法成员,不能修饰类(内部类除外)。
子类能访问 protected 修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。
下面的父类使用了 protected 访问修饰符,子类重写了父类的 openSpeaker() 方法。
class AudioPlayer {
protected boolean openSpeaker(Speaker sp) {
// 实现细节
}
}
class StreamingAudioPlayer extends AudioPlayer {
protected boolean openSpeaker(Speaker sp) {
// 实现细节
}
}
如果把 openSpeaker() 方法声明为 private,那么除了 AudioPlayer 之外的类将不能访问该方法。
如果把 openSpeaker() 声明为 public,那么所有的类都能够访问该方法。
如果我们只想让该方法对其所在类的子类可见,则将该方法声明为 protected。
访问控制和继承
请注意以下方法继承的规则:
父类中声明为 public 的方法在子类中也必须为 public。
父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。
父类中声明为 private 的方法,不能够被继承。