Day11目标:
-
理解封装的意义;
-
掌握访问控制修饰符;
-
掌握static关键字;
-
掌握static final常量;
-
掌握枚举的使用;
-
预计代码量:课上180行、作业360行
访问控制修饰符
Java访问权限概述
对于任意一个类,其成员(包括成员变量和成员方法)能否被其它类所访问,取决于该成员的修饰词。在Java中,类成员的访问权限修饰词有4个:
-
private
:私有的权限; -
default(空)
:默认包访问权限; -
public
:公开的权限; -
protected
:受保护的权限;
其访问控制权限如下表:
protected的可见性
-
父类中的protect成员(包括成员变量及方法)对当前包内可见,且对子类可见;
-
若子类与父类不在同一包中,那么子类只有在实例访问它从父类继承而来的protected方法,而在子类中不能访问父类实例的protected方法;
-
不论是否在一个包内,父类中可以访问子类实例(对象)继承的父类protected修饰的方法;
-
若子类与父类不在同一个包中,子类只能在自己的类中访问父类继承的protected成员,无法访问其他子类实例(即便同父类的亲兄弟)所继承的protected修饰的方法;
-
若子类与父类不在同一个包中,父类不可以使用子类实例调用子类中protected修饰的成员。
static关键字
静态变量是成员变量的一种,静态变量存储在方法区中,则它在类加载时就会进行初始化,所以静态变量访问的时候不需要创建实例(对象),直接可以通过类名来访问;
什么时候使用静态变量?
public class StaticTest01 {
public static void main(String[] args) {
Chinese c1 = new Chinese("张三", "333333333333", "中国");
System.out.print("姓名:" + c1.name);
System.out.print(" 身份证号:" + c1.idNum);
System.out.println(" 国籍:" + c1.nation);
Chinese c2 = new Chinese("李四", "444444444444", "中国");
System.out.print("姓名:" + c2.name);
System.out.print(" 身份证号:" + c2.idNum);
System.out.println(" 国籍:" + c2.nation);
}
}
class Chinese {
// 姓名; 实例变量
String name;
//身份证号; 实例变量
String idNum;
//国籍; 实例变量
String nation;
//无参构造器
public Chinese() {}
//有参构造器
public Chinese(String myName, String myIdNum, String myNation) {
this.name = myName;
this.idNum = myIdNum;
this.nation = myNation;
}
}
输出结果:
姓名:张三 身份证号:333333333333 国籍:中国
姓名:李四 身份证号:444444444444 国籍:中国
这个Chinese类抽象的是中国人,所以“国籍”这个实例变量就可以声明为静态变量,让国籍固定为Chinese;访问时只需要用Chinese类来访问就可以了:
public class StaticTest02 {
public static void main(String[] args) {
Chinese c1 = new Chinese("张三", "333333333333");
System.out.print("姓名:" + c1.name);
System.out.print(" 身份证号:" + c1.idNum);
// 静态变量不需要实例化,只需要用类来访问就可以了
System.out.println(" 国籍:" + Chinese.nation); // 类名. 来访问
Chinese c2 = new Chinese("李四", "444444444444");
System.out.print("姓名:" + c2.name);
System.out.print(" 身份证号:" + c2.idNum);
System.out.println(" 国籍:" + Chinese.nation); // 类名. 来访问
}
}
class Chinese {
// 姓名; 实例变量
String name;
//身份证号; 实例变量
String idNum;
//国籍; 静态变量
static String nation = "中国";
//无参构造器
public Chinese() {}
//有参构造器
public Chinese(String myName, String myIdNum) {
this.name = myName;
this.idNum = myIdNum;
}
}
如果这个类的所有对象的属性值都是一样的,不建议定义为实例变量,会浪费内存空间;建议定义为静态变量,在方法区中只保留一份,节省内存的开销;
静态块
-
由static修饰的语句块即为静态块;
-
静态块属于类,在类加载期间自动执行,一个类只被加载一次,静态块只执行一次。
public class StaticBlock { static { System.out.println("静态块"); } StaticBlock() { System.out.println("构造方法"); } public static void main(String[] args) { StaticBlock o1 = new StaticBlock(); StaticBlock o2 = new StaticBlock(); StaticBlock o3 = new StaticBlock(); } }
输出结果:
静态块 构造方法 构造方法 构造方法
static final常量
由static final 修饰的成员变量称为常量,建议常量命名全大写,多单词用下划线分隔,必须在生命的同时初始化,常通过类名访问,不可以改变!
class Loo {
public static final double PI = 3.14159;
public static final int NUM; // 编译错误,必须声明同时初始化
}
public class StaticFinalDemo {
public static void main(String[] args) {
System.out.println(Loo.PI);
Loo.PI = 3.15; // 编译错误
}
}
枚举
-
枚举是一种引用类型;
-
枚举类型的对象数目是固定的,常常用于定义一组变量,就例如:季节、星期、月份、订单状态等;
-
枚举的构造方法都是私有的
-
枚举的第一行默认都是罗列枚举对象的名称。
enum Season { SPRING, SUMMER, AUTUMN, WINTTER; // 枚举对象(常量) }
- 枚举都继承自Enum类,其中提供了一组方法供我们使用:
public class EnumTest { publlic static void main(String[] args) { Seasons[] seasons = Seasons.values(); // 获取所有枚举对象 } }