JAVA课程第八次实验课程主要知识点示例
一、题目背景
某学校需要开发简易人员管理系统,涉及学生和教师两类人员。要求通过面向对象设计,实现人员信息的存储、访问控制及类型判断,具体需求如下:
二、需求说明
2.1 基础类设计(父类)
创建包com.school.base,定义父类Person(所有人员的基类):
成员变量(4 种权限):
public String name(姓名,公开访问)
protected int age(年龄,子类可访问)
String gender(性别,默认权限,仅同包可见)
private String idCard(身份证号,仅本类可见)
构造方法:public Person(String name, int age, String gender, String idCard)(初始化所有成员)
公共方法:public String getIdCard()(返回身份证号,供外部间接访问私有成员)、public void showBaseInfo()(打印 “姓名:XX,年龄:XX”)
2.2 子类设计(跨包继承)
2.2.1 学生类
创建包com.school.student,定义子类Student extends com.school.base.Person(学生类):
新增成员:public String studentId(学号)、private double score(成绩)
构造方法:public Student(String name, int age, String gender, String idCard, String studentId, double score)(初始化所有成员)
公共方法:public double getScore()(返回成绩)、public void showStudentInfo()(打印 “姓名:XX,年龄:XX,学号:XX,成绩:XX”,需使用继承的父类成员和自身成员)
2.2.2 教师类
创建包com.school.teacher,定义子类Teacher extends com.school.base.Person(教师类):
新增成员:public String teacherId(教师编号)、protected String subject(教授科目,子类可访问)
构造方法:public Teacher(String name, int age, String gender, String idCard, String teacherId, String subject)(初始化所有成员)
公共方法:public void showTeacherInfo()(打印 “姓名:XX,年龄:XX,教师编号:XX,科目:XX”,需使用继承的父类成员和自身成员)
2.2.3 管理类
管理类设计(测试权限与 instanceof)
创建包com.school.manager,定义管理类PersonManager:
方法public static void printInfo(Person p):
若p是Student实例(用instanceof判断),调用showStudentInfo()
若p是Teacher实例,调用showTeacherInfo()
打印 “是否为 Person 实例:XX”(用instanceof判断)
方法public static void testPermission(Person p):
尝试访问p.name(public,允许)、p.age(protected,跨包不可直接访问,需注释并说明)、p.gender(默认权限,跨包不可访问,需注释并说明)
通过p.getIdCard()访问身份证号(允许)
2.3 主程序(测试类)
创建包com.school,定义Main类,在main方法中:
创建 1 个Student对象(示例:姓名 “张三”,年龄 18,性别 “男”,身份证号 “110XXX”,学号 “2024001”,成绩 90.5)
创建 1 个Teacher对象(示例:姓名 “李四”,年龄 35,性别 “女”,身份证号 “120XXX”,教师编号 “T202401”,科目 “数学”)
调用PersonManager.printInfo(student)和PersonManager.printInfo(teacher),验证类型判断
调用PersonManager.testPermission(student),验证跨包权限访问
三、示例代码
3.1 创建空包
完成本次作业,我们可以新创建一个空的包,本次作业所有的内容均放在此包里面。

3.2 定义父类Person类
根据题目要求,创建空包。

在base包里面定义父类Person

其他的代码按照题目的要求一步一步的完成。代码示例如下所示。
public class Person {public String name; // 公开权限protected int age; // 受保护权限String gender; // 默认权限(仅com.school.base包可见)private String idCard; // 私有权限public Person(String name, int age, String gender, String idCard) {this.name = name;this.age = age;this.gender = gender;this.idCard = idCard;}// 公共方法:获取私有身份证号public String getIdCard() {return idCard;}// 打印基础信息public void showBaseInfo() {System.out.println("姓名:" + name + ",年龄:" + age);}
}
3.3 子类设计
3.3.1 学生类
首先按照题目要求新建包

新建后代码结构如图所示:

新建Student类:

按照题目要求完成代码:
import Ex9.com.school.base.Person;public class Student extends Person {public String studentId; // 学号private double score; // 成绩(私有)// 构造方法:调用父类构造初始化继承的成员public Student(String name, int age, String gender, String idCard, String studentId, double score) {super(name, age, gender, idCard);this.studentId = studentId;this.score = score;}// 获取私有成绩public double getScore() {return score;}// 打印学生完整信息(使用继承的父类成员)public void showStudentInfo() {// 访问父类的public和protected成员(跨包子类允许)System.out.println("学生信息:姓名=" + name + ",年龄=" + age +",学号=" + studentId + ",成绩=" + getScore());}
}
注释:
super关键字是调用父类构造方法来初始化父类属性。
如下图中所示,如果我们在子类使用Student类来初始化继承的name, age, gender, idCard,其中gender,idCard会报错,因为他们分别为友好类和private,这会导致报错。

3.3.2 教师类
创建teacher包和Teacher类

与student类基本相同,代码如下。
public class Teacher extends Person {public String teacherId; // 教师编号protected String subject; // 教授科目(受保护)// 构造方法:调用父类构造public Teacher(String name, int age, String gender, String idCard, String teacherId, String subject) {super(name, age, gender, idCard);this.teacherId = teacherId;this.subject = subject;}// 打印教师完整信息public void showTeacherInfo() {System.out.println("教师信息:姓名=" + name + ",年龄=" + age +",教师编号=" + teacherId + ",科目=" + subject);}
}
3.3.3 管理类
按题目要求创建管理包和类。

import Ex9.com.school.base.Person;
import Ex9.com.school.student.Student;
import Ex9.com.school.teacher.Teacher;public class PersonManager {// 打印人员信息(用instanceof判断类型)public static void printInfo(Person p) {if (p instanceof Student) {((Student) p).showStudentInfo(); // 强转为Student调用子类方法} else if (p instanceof Teacher) {((Teacher) p).showTeacherInfo(); // 强转为Teacher调用子类方法}// 判断是否为Person实例(所有子类对象都是Person的实例)System.out.println("是否为Person实例:" + (p instanceof Person));}// 测试跨包权限访问public static void testPermission(Person p) {System.out.println("\n权限测试:");System.out.println("访问public成员name:" + p.name); // 跨包可访问// System.out.println("访问protected成员age:" + p.age); // 错误:不同包的非子类(PersonManager不是Person的子类)不能访问protected成员// System.out.println("访问默认权限gender:" + p.gender); // 错误:默认权限仅同包(com.school.base)可见,跨包不可访问System.out.println("通过公共方法访问private idCard:" + p.getIdCard()); // 间接访问}
}
3.4 主类

主要进行测试,代码如下:
import Ex9.com.school.manager.PersonManager;
import Ex9.com.school.student.Student;
import Ex9.com.school.teacher.Teacher;public class Main {public static void main(String[] args) {// 创建学生和教师对象Student student = new Student("张三", 18, "男", "110101XXXX", "2024001", 90.5);Teacher teacher = new Teacher("李四", 35, "女", "120101XXXX", "T202401", "数学");// 打印信息(验证instanceof和类型转换)System.out.println("=== 学生信息 ===");PersonManager.printInfo(student);System.out.println("\n=== 教师信息 ===");PersonManager.printInfo(teacher);// 测试权限访问PersonManager.testPermission(student);}
}
3.4 主类运行结果
最后的代码结构:

运行出来的结果:

四.核心知识点说明
4.1 继承与跨包
Student和Teacher跨包继承Person,通过extends关键字建立父子关系,子类可复用父类的public和protected成员。
4.2权限控制
public成员(如name):任何类可访问;
protected成员(如age):仅本类、同包子类、不同包子类可访问(非子类如PersonManager不可访问);
默认权限(如gender):仅同包类可访问,跨包(包括子类)不可访问;
private成员(如idCard):仅本类可访问,需通过公共方法(getIdCard())间接获取。
权限大小:public>protected>友好类(默认权限)>private
4.3 instanceof 运算符
用于判断对象实际类型(如student instanceof Student为true,student instanceof Person也为true,因子类是父类的实例),结合类型转换可调用子类特有方法。
