1 包、final
1.1 包
包在Java中相当于文件系统中的文件夹,用来管理各种不同功能的java类,方便后期代码维护
包名命名规范:
公司域名反写 + 包的作用
全部使用英文小写,做到见名知意
例如:
com.yq.domain
全类名(全限定名):包名 + 类名,如 com.yq.domain.Student
使用其他包中的类时,需要遵循以下规则:
使用其他类的规则:
使用其他类时,需要使用全类名
格式:import 关键字导包
- 使用同一个包中的类时,不需要导包
Student s = new Student();
- 使用java.lang包中的类时,不需要导包
String str = "Hello World";
- 其他情况都需要导包
import com.yq.a06domain1.Teacher;
- 如果同时使用两个包中的同类名,需要用全类名
com.yq.a06domain1.Teacher t1 = new com.yq.a06domain1.Teacher();
com.yq.a06domain2.Teacher t2 = new com.yq.a06domain2.Teacher();练习:
# 文件结构
a05test
- Student.java
- Test.java
a06domain1
- Teacher.java
a06domain2
- Teacher.java//Student.java
package com.yq.a05test;
public class Student {
private String name;
private int age;
// 构造方法
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
// getter和setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//Teacher.java
package com.yq.a06domain1;
public class Teacher {
private String name;
private int age;
//构造方法
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
//getter和setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//Test.java - 演示不同情况下的包使用
package com.yq.a05test;
import com.yq.a06domain1.Teacher;
public class Test {
public static void main(String[] args) {
// 情况1:使用同包类,无需导包
Student s = new Student();
s.setName("张三");
s.setAge(23);
System.out.println(s.getName() + ", " + s.getAge());
// 情况2:使用java.lang包,无需导包
String str = "abc";
System.out.println(str);
// 情况3:使用其他包类,需要导包
// Teacher t = new Teacher(); // 已通过import导包
// 情况4:同名类冲突,使用全类名
com.yq.a06domain1.Teacher t1 = new com.yq.a06domain1.Teacher("zhangsan", 23);
com.yq.a06domain2.Teacher t2 = new com.yq.a06domain2.Teacher("lisi", 24);
System.out.println(t1.getName() + ", " + t1.getAge());
System.out.println(t2.getName() + ", " + t2.getAge());
}
}1.2 final
final关键字用于表示"不可改变的",可以修饰类、方法和变量:
final修饰方法:该方法成为最终方法,不能被重写
final修饰类:该类成为最终类,不能被继承
final修饰变量:该变量成为常量,只能被赋值一次
package com.yq.a07final01;
public class Test {
public static void main(String[] args) {
//final修饰变量:
// 叫做常量,只能被赋值一次
final int a = 10;
System.out.println(a);
//a = 20; //final修饰变量 叫做常量,只能被赋值一次, 不能被修改
}
}
//final class Fu { //使用final 表明该类是最终类,不能被继承
class Fu {
//public final void show() { //使用final 表明该方法时最终方法,不能被重写
public void show(){
System.out.println("父类的show方法");
}
}
class Zi extends Fu {
@Override
public void show() {
System.out.println("子类的show方法");
}
}注意事项
常量:
实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性
常量的命名规范:
- 单个单词: 全部大写
- 多个单词: 全部大写,单词之间用下划线隔开
细节:
final修饰的变量是基本变量时,那么变量存储的数据值不能发生改变
final修饰的变量是引用类型时,那么变量存储的地址值不能发生改变, 对象内部可以改变
字符串是不可变的: 因为 final修饰了//Test.java
package com.yq.a08final02;
public class Test {
public static void main(String[] args) {
/*
final修饰的变量是基本变量时,那么变量存储的 数据值 不能发生改变
final修饰的变量是引用类型时,那么变量存储的 地址值 不能发生改变, 对象内部可以改变
核心:
常量记录的数值是不能发生改变的
字符串是不可变的: 因为 final修饰了
*/
final double PI = 3.14;
//PI = 123; //final修饰的变量是基本变量时,那么变量存储的数据值不能发生改变
//创建对象
final Student S = new Student("zhangsan", 23);
S.setName("lisi");
S.setAge(24);
System.out.println(S.getName() + ", " + S.getAge());
//S = new Student(); //final修饰的变量是引用类型时,那么变量存储的地址值不能发生改变, 对象内部可以改变
//数组
final int[] ARR = {1, 2, 3, 4};
//ARR = new int[10]
ARR[0] = 10;
ARR[1] = 20;
for (int i = 0; i < ARR.length; i++) {
System.out.println(ARR[i]);
}
}
}
//Student.java
package com.yq.a08final02;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
常量练习:
将学生管理系统中用户的操作改为常量的形式
public class StudentSystem {
// 使用常量代替魔法数字,提高可读性
private static final String ADD_STUDENT = "1";
private static final String DELETE_STUDENT = "2";
private static final String UPDATE_STUDENT = "3";
private static final String QUERY_STUDENT = "4";
private static final String EXIT = "5";
public static void startStudentSystem() {
ArrayList<Student> list = new ArrayList<>();
loop: while (true){
System.out.println("----------欢迎来到学生管理系统----------");
System.out.println("1.添加学生");
System.out.println("2.删除学生");
System.out.println("3.修改学生");
System.out.println("4.查询学生");
System.out.println("5.退出");
Scanner sc = new Scanner(System.in);
String choose = sc.next();
switch (choose){
case ADD_STUDENT -> addStudent(list);
case DELETE_STUDENT -> deleteStudent(list);
case UPDATE_STUDENT -> updateStudent(list);
case QUERY_STUDENT -> queryStudent(list);
case EXIT -> {
System.out.println("退出");
//break; //只能跳出单层循环 此处只能跳出switch
//break loop; //方法1 用loop标记
System.exit(0); //方法2 停止虚拟机运行
}
default -> System.out.println("没有这个选项");
}
}
}
}2 权限修饰符、代码块
2.1 权限修饰符
权限修饰符:用来控制一个成员能够被访问的范围
可以修饰成员变量、方法、构造方法、内部类
// private即是权限修饰符 public class Student { private String name; private int age; }权限修饰符的分类
四种权限修饰符的作用范围(从小到大)(private < 空着不写 < protected < public ):
记忆技巧:
private:像私房钱,只能自己用默认:像家庭资产,全家可用protected:像家族资产,家人和亲戚可用public:像公共设施,所有人都可用
// demo1/Animal.java - 基类 package com.yq.a10demo1; public class Animal { public String name; // public修饰,所有地方都可访问 public void show() { System.out.println(name); } } // demo1/Test.java - 同一个包中的测试类 package com.yq.a10demo1; public class Test { public static void main(String[] args) { Animal a = new Animal(); System.out.println(a.name); // 可以访问public成员 } } // demo2/Dog.java - 不同包中的子类 package com.yq.a11demo2; import com.yq.a10demo1.Animal; public class Dog extends Animal { public void show() { System.out.println(name); // 可以访问父类的public成员 } } // demo2/Test.java package com.yq.a11demo2; import com.yq.a10demo1.Animal; public class Test { public static void main(String[] args){ Animal a = new Animal(); System.out.println(a.name); } }
权限修饰符的使用规则:
实际开发中,一般只用private或者public
成员变量私有化:使用
private修饰方法公开化:使用
public修饰
特例:如果方法中的代码是抽取其他方法中共性代码,这个方法一般也私有,使用 private(比如 ArrayList 中grow方法)
2.2 代码块
局部代码块(写在方法中的代码块 ,为了节约内存)
public class Test { public static void main(String[] args) { // 局部代码块 { int a = 10; // a的作用域仅限于该代码块 System.out.println(a); } // System.out.println(a); // 编译错误:a已超出作用域 } }构造代码块
可以将多个重复的代码,放入构造代码块中
//Student.java package com.yq.a12codeblockdemo1; public class Student { private String name; private int age; //构造代码块 //1.写在成员位置的代码块 //2.作用:可以把多个构造方法中,重复的部分抽取出来 //3.执行时机:在创建本类对象时,会先执行构造代码块,再执行构造方法 //逐渐被淘汰,不够灵活(因为必定会执行) // 构造代码块 { System.out.println("开始创建对象了"); // 所有构造方法都会执行 } public Student() { System.out.println("空参构造"); } public Student(String name, int age) { System.out.println("有参构造"); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } //CodeBlockDemo1.java package com.yq.a12codeblockdemo1; public class CodeBlockDemo1 { public static void main(String[] args) { /*{ int a = 10; }*/ //代码块结束以后,变量a就从内存中消失了 // System.out.println(a); //创建对象 Student s = new Student(); Student s2 = new Student("zhangsan", 23); } }
执行时机:在创建对象时,先执行构造代码块,再执行构造方法。
注意:构造代码块在实际开发中逐渐被淘汰,推荐使用
this()调用或提取公共方法的方式。
静态代码块
格式:
static { }特点:
使用
static关键字修饰随着类的加载而执行
自动触发且只执行一次
使用场景:在类加载时进行数据初始化。
应用示例 - 学生管理系统初始化:
注意:需要将static代码块部分与main方法独立,否则main方法在被调用时,初始化部分也可以被调用
//App.java public class App { // 静态变量 static ArrayList<User> list = new ArrayList<>(); // 静态代码块 - 类加载时执行初始化 static { //添加一些用户信息 list.add(new User("zhangsan","123456","110101200001011234","12333211234")); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (true) { System.out.println("欢迎来到学生管理系统"); System.out.println("请选择操作: 1登录 2注册 3忘记密码 4退出"); String choose = sc.next(); switch (choose) { case "1" -> { login(list); //System.out.println("登录"); } case "2" -> register(list); case "3" -> forGetPassword(list); case "4" -> { System.out.println("谢谢使用, 再见"); System.exit(0); } default -> System.out.println("没有这个选项, 请重新输入"); } } } //StudentSystem.java public class StudentSystem { // 静态变量 static ArrayList<Student> list = new ArrayList<>(); // 静态代码块 - 类加载时执行初始化 static { //添加一些用户信息 list.add(new Student("001","zhangsan",23,"beijing")); } public static void startStudentSystem() { loop: while (true){ System.out.println("----------欢迎来到学生管理系统----------"); System.out.println("1.添加学生"); System.out.println("2.删除学生"); System.out.println("3.修改学生"); System.out.println("4.查询学生"); System.out.println("5.退出"); Scanner sc = new Scanner(System.in); String choose = sc.next(); switch (choose){ case ADD_STUDENT -> addStudent(list); case DELETE_STUDENT -> deleteStudent(list); case UPDATE_STUDENT -> updateStudent(list); case QUERY_STUDENT -> queryStudent(list); case EXIT -> { System.out.println("退出"); //break; //只能跳出单层循环 此处只能跳出switch //break loop; //方法1 用loop标记 System.exit(0); //方法2 停止虚拟机运行 } default -> System.out.println("没有这个选项"); } } } }
评论区