封装的实现

封装的概念

  • 将类的某些信息隐藏在类内部,不允许外部程序直接访问
  • 通过该类提供的方法来实现对隐藏信息的操作和访问
  • 隐藏对象的信息
  • 留出访问的接口

封装的特点

  • 只能通过规定的方法访问数据
  • 隐藏类的实现细节,方便修改和实现

封装的实现

image.png

cat.java
#Alt + Shift + S => Generate Getters and Setters:生成类的set 和 get方法

  1. package com.demo;
  2. /**
  3. * @author 宠物猫类
  4. *
  5. */
  6. public class Cat {
  7. private String name;
  8. private int age;
  9. private double weight;
  10. private String species;
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public int getAge() {
  18. return age;
  19. }
  20. public void setAge(int age) {
  21. if (age > 0) {
  22. this.age = age;
  23. }
  24. }
  25. public double getWeight() {
  26. return weight;
  27. }
  28. public void setWeight(double weight) {
  29. this.weight = weight;
  30. }
  31. public String getSpecies() {
  32. return species;
  33. }
  34. public void setSpecies(String species) {
  35. this.species = species;
  36. }
  37. }

catTest.java

  1. package com.demo;
  2. public class CatTest {
  3. public static void main(String[] args) {
  4. // 对象实例化
  5. Cat cat1 = new Cat();
  6. cat1.setName("kitty");
  7. cat1.setAge(2);
  8. cat1.setWeight(2.5);
  9. cat1.setSpecies("中华田园猫");
  10. System.out.println(cat1.getName());
  11. System.out.println(cat1.getAge());
  12. System.out.println(cat1.getWeight());
  13. System.out.println(cat1.getSpecies());
  14. }
  15. }

使用包进行类管理

作用:管理Java文件,解决同名文件冲突问题

创建包

  • 一个包里不能存在同名类
  • 包的命名规则:域名倒序 + 模块 + 功能 #域名全部小写
  • 定义包的语句,必须放在Java源文件中的第一行
  • 建议每个包内存储信息功能单一,即单一职责原则

导入包

  • 建议采用”import 包名.类名”的方式加载,提高效率
  • 加载类的顺序跟import导入语句的位置无关
  • “ import 包名.* “ 只能访问指定包名下的类,无法访问子包下的类

导入所有的类

  1. package com.imooc; // 定义包
  2. import com.demo.*; // 导入com.demo下所有的类
  3. public class HelloImooc {
  4. public static void main(String[] args) {
  5. Cat cat1 = new Cat();
  6. CatTest cat2 = new CatTest();
  7. }
  8. }

导入指定的类

  1. package com.imooc; // 定义包
  2. import com.demo.Cat; // 导入com.demo下指定的类
  3. import com.demo.CatTest; // 导入com.demo下指定的类
  4. public class HelloImooc {
  5. public static void main(String[] args) {
  6. Cat cat1 = new Cat();
  7. CatTest cat2 = new CatTest();
  8. }
  9. }

导入不同包中同名的类

  1. package com.imooc; // 定义包
  2. import com.demo.*; // 导入com.demo下所有的类
  3. import com.dev.*; // 导入com.dev下所的类
  4. public class HelloImooc {
  5. public static void main(String[] args) {
  6. com.demo.Cat cat1 = new com.demo.Cat();
  7. com.dev.Cat cat2 = new com.dev.Cat();
  8. }
  9. }

image.png

static关键字

静态属性和静态方法

  • 类对象共享
  • 类加载时产生,销毁时释放,生命周期长,即所有的类对象销毁时释放
  • static + 属性,称之为类属性 / 静态属性
  • static + 方法,称之为类方法 / 静态方法
  • 推荐调用静态属性/方法的方式是,类名.静态成员
  • 静态方法中不能直接访问非静态成员,只能直接调用静态成员

image.png

静态代码块和构造代码块

  • 静态代码块:类加载时调用,优于构造代码块执行
  • 构造代码块:创建对象时调用,优于构造方法执行
  • 在类中可以有多个静态代码块和构造代码块
  • 无论产生多少类实例,静态代码块只执行一次

Cat.java

  1. package com.demo;
  2. /**
  3. * @author 宠物猫类
  4. *
  5. */
  6. public class Cat {
  7. private String name;
  8. private int age;
  9. private double weight;
  10. private String species;
  11. public Cat(){
  12. System.out.println("demo - cat");
  13. }
  14. static{
  15. System.out.println("我是静态代码块1");
  16. }
  17. static{
  18. System.out.println("我是静态代码块2");
  19. }
  20. {
  21. System.out.println("我是构造代码块1");
  22. }
  23. {
  24. System.out.println("我是构造代码块2");
  25. }
  26. public String getName() {
  27. return name;
  28. }
  29. ...省略...
  30. }

CatTest.java

  1. package com.demo;
  2. public class CatTest {
  3. public CatTest(){
  4. System.out.println("demo - CatTest");
  5. }
  6. public static void main(String[] args) {
  7. // 对象实例化
  8. Cat cat1 = new Cat();
  9. Cat cat2 = new Cat();
  10. }
  11. }

输出结果:
我是静态代码块1
我是静态代码块2

我是构造代码块1
我是构造代码块2
demo - cat

我是构造代码块1
我是构造代码块2
demo - cat

实例:
model - Subject.java

  1. package com.imooc.model;
  2. /**
  3. * 专业类
  4. *
  5. * @author 57681
  6. *
  7. */
  8. public class Subject {
  9. // 成员属性:专业名称,专业编号,学制年限
  10. private String subjectName;
  11. private String subjectNo;
  12. private int subjectLife;
  13. private Student[] myStudents;
  14. private int studentNum;
  15. // 无参构造方法
  16. public Subject() {
  17. }
  18. // 带参构造方法,实现对属性专业名称,专业编号,学制年限的赋值
  19. public Subject(String subjectName, String subjectNo, int subjectLife) {
  20. this.setSubjectName(subjectName);
  21. this.setSubjectNo(subjectNo);
  22. this.setSubjectLife(subjectLife);
  23. }
  24. // 带参构造方法,实现对属性的全部赋值
  25. public Subject(String subjectName, String subjectNo, int subjectLife, Student[] myStudents) {
  26. this.setSubjectName(subjectName);
  27. this.setSubjectNo(subjectNo);
  28. this.setSubjectLife(subjectLife);
  29. this.setMyStudents(myStudents);
  30. }
  31. public String getSubjectName() {
  32. return subjectName;
  33. }
  34. public void setSubjectName(String subjectName) {
  35. this.subjectName = subjectName;
  36. }
  37. public String getSubjectNo() {
  38. return subjectNo;
  39. }
  40. public void setSubjectNo(String subjectNo) {
  41. this.subjectNo = subjectNo;
  42. }
  43. public int getSubjectLife() {
  44. return subjectLife;
  45. }
  46. // 设置学制年限,限制必须大于0
  47. public void setSubjectLife(int subjectLife) {
  48. if (subjectLife > 0) {
  49. this.subjectLife = subjectLife;
  50. }
  51. }
  52. /**
  53. * 获取选修专业的学生信息,如果保存学生信息的数组未被初始化,则初始化长度为200
  54. *
  55. * @return
  56. */
  57. public Student[] getMyStudents() {
  58. if (myStudents == null) {
  59. myStudents = new Student[200];
  60. }
  61. return myStudents;
  62. }
  63. public void setMyStudents(Student[] myStudents) {
  64. this.myStudents = myStudents;
  65. }
  66. public int getStudentNum() {
  67. return studentNum;
  68. }
  69. public String info() {
  70. return "专业名称:" + this.getSubjectName() + "\n专业编号:" + this.getSubjectNo() + "\n学制年限:" + this.getSubjectLife();
  71. }
  72. public void addStudent(Student stu) {
  73. // 1.将学生保存到数组
  74. // 2.将学生个数保存到studengNum
  75. for (int i = 0; i < this.getMyStudents().length; i++) {
  76. if (this.getMyStudents()[i] == null) {
  77. stu.setStudentSubject(this);
  78. this.getMyStudents()[i] = stu;
  79. this.studentNum = i + 1;
  80. return;
  81. }
  82. }
  83. }
  84. }

model - Student.java

  1. package com.imooc.model;
  2. /**
  3. * 学生类
  4. *
  5. * @author 57681
  6. *
  7. */
  8. public class Student {
  9. // 成员属性:学号,姓名,性别,年龄
  10. private String studentNo;
  11. private String studentName;
  12. private String studentSex;
  13. private int studentAge;
  14. private Subject studentSubject;
  15. // 无参构造方法
  16. public Student() {
  17. }
  18. // 带参构造方法,实现对属性学号,姓名,性别,年龄的赋值
  19. public Student(String studentNo, String studentName, String studentSex, int studentAge) {
  20. this.setStudentNo(studentNo);
  21. this.setStudentName(studentName);
  22. this.setStudentSex(studentSex);
  23. this.setStudentAge(studentAge);
  24. }
  25. // 带参构造方法,实现对属性的全部赋值
  26. public Student(String studentNo, String studentName, String studentSex, int studentAge, Subject studentSubject) {
  27. this.setStudentNo(studentNo);
  28. this.setStudentName(studentName);
  29. this.setStudentSex(studentSex);
  30. this.setStudentAge(studentAge);
  31. this.setStudentSubject(studentSubject);
  32. }
  33. public String getStudentNo() {
  34. return studentNo;
  35. }
  36. public void setStudentNo(String studentNo) {
  37. this.studentNo = studentNo;
  38. }
  39. public String getStudentName() {
  40. return studentName;
  41. }
  42. public void setStudentName(String studentName) {
  43. this.studentName = studentName;
  44. }
  45. public String getStudentSex() {
  46. return studentSex;
  47. }
  48. public void setStudentSex(String studentSex) {
  49. if (studentSex == "男" || studentSex == "女") {
  50. this.studentSex = studentSex;
  51. } else {
  52. this.studentSex = "男";
  53. }
  54. }
  55. public int getStudentAge() {
  56. return studentAge;
  57. }
  58. public void setStudentAge(int studentAge) {
  59. if (studentAge < 10 || studentAge > 100) {
  60. this.studentAge = 18;
  61. } else {
  62. this.studentAge = studentAge;
  63. }
  64. }
  65. /**
  66. * 获取专业对象,如果没有实例化,先实例化后再返回
  67. *
  68. * @return 专业对象信息
  69. */
  70. public Subject getStudentSubject() {
  71. if (studentSubject == null) {
  72. studentSubject = new Subject();
  73. }
  74. return studentSubject;
  75. }
  76. public void setStudentSubject(Subject studentSubject) {
  77. this.studentSubject = studentSubject;
  78. }
  79. /**
  80. * 学生介绍的方法
  81. */
  82. public String info() {
  83. return "学号:" + this.getStudentNo() + "\n姓名:" + this.getStudentName() + "\n性别:" + this.getStudentSex() + "\n年龄:"
  84. + this.getStudentAge() + "\n专业名称:" + this.getStudentSubject().getSubjectName() + "\n专业编号:"
  85. + this.getStudentSubject().getSubjectNo() + "\n学制年限:" + this.getStudentSubject().getSubjectLife();
  86. }
  87. }

test - SchoolTest.java

  1. package com.imooc.test;
  2. import com.imooc.model.*;
  3. public class SchoolTest {
  4. public static void main(String[] args) {
  5. Subject sub1 = new Subject("计算机科学与技术", "J0001", 4);
  6. Student stu1 = new Student("S01", "张三", "男", 20);
  7. Student stu2 = new Student("S02", "李四", "女", 19);
  8. Student stu3 = new Student("S03", "王五", "男", 21);
  9. sub1.addStudent(stu1);
  10. sub1.addStudent(stu2);
  11. sub1.addStudent(stu3);
  12. System.out.println(sub1.getStudentNum());
  13. }
  14. }