18 changed files with 255 additions and 0 deletions
@ -0,0 +1,9 @@ |
|||||
|
package w5基础版; |
||||
|
|
||||
|
// 圆
|
||||
|
public class Circle extends Shape { |
||||
|
@Override |
||||
|
public void draw() { |
||||
|
System.out.println("🔵 绘制圆形"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
package w5基础版; |
||||
|
|
||||
|
// 矩形
|
||||
|
public class Rectangle extends Shape { |
||||
|
@Override |
||||
|
public void draw() { |
||||
|
System.out.println("🔲 绘制矩形"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
package w5基础版; |
||||
|
|
||||
|
// 父类
|
||||
|
public class Shape { |
||||
|
// draw方法
|
||||
|
public void draw() { |
||||
|
System.out.println("绘制图形"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
package w5基础版; |
||||
|
|
||||
|
// 测试类
|
||||
|
public class TestShape { |
||||
|
public static void main(String[] args) { |
||||
|
// 1. 创建对象
|
||||
|
Shape circle = new Circle(); |
||||
|
Shape rectangle = new Rectangle(); |
||||
|
|
||||
|
// 2. 调用统一绘制方法
|
||||
|
drawShape(circle); |
||||
|
drawShape(rectangle); |
||||
|
|
||||
|
// 3. 直接调用
|
||||
|
System.out.println("\n=== 直接调用 ==="); |
||||
|
circle.draw(); |
||||
|
rectangle.draw(); |
||||
|
} |
||||
|
|
||||
|
// 核心方法:接收父类引用,实现多态调用
|
||||
|
public static void drawShape(Shape s) { |
||||
|
s.draw(); |
||||
|
} |
||||
|
} |
||||
|
After Width: | Height: | Size: 89 KiB |
@ -0,0 +1,20 @@ |
|||||
|
package w5挑战版; |
||||
|
// 人类(父类)
|
||||
|
public class Person { |
||||
|
private String name; |
||||
|
private int age; |
||||
|
|
||||
|
public Person(String name, int age) { |
||||
|
this.name = name; |
||||
|
this.age = age; |
||||
|
} |
||||
|
|
||||
|
// Getter
|
||||
|
public String getName() { return name; } |
||||
|
public int getAge() { return age; } |
||||
|
|
||||
|
// 通用方法
|
||||
|
public void showInfo() { |
||||
|
System.out.println("姓名:" + name + ",年龄:" + age); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
package w5挑战版; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.ArrayList; |
||||
|
|
||||
|
// 人员管理器(重构关键)
|
||||
|
public class PersonManager { |
||||
|
// 用List存储Person,容纳所有子类对象
|
||||
|
private List<Person> personList = new ArrayList<>(); |
||||
|
|
||||
|
// 核心重构:合并成一个方法,接收父类引用
|
||||
|
public void addPerson(Person person) { |
||||
|
personList.add(person); |
||||
|
System.out.println("添加成功:" + person.getClass().getSimpleName()); |
||||
|
} |
||||
|
|
||||
|
// 显示所有人信息(多态调用)
|
||||
|
public void showAllPersons() { |
||||
|
System.out.println("\n=== 所有人员列表 ==="); |
||||
|
for (Person p : personList) { |
||||
|
p.showInfo(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 解决特定属性问题:使用instanceof判断类型并获取属性
|
||||
|
public void checkPersonDetails() { |
||||
|
System.out.println("\n=== 人员详情检查 ==="); |
||||
|
for (Person p : personList) { |
||||
|
if (p instanceof Student) { |
||||
|
Student s = (Student) p; |
||||
|
// 现在Student有了getStudentId(),就不会报错了
|
||||
|
System.out.println(s.getName() + " 是学生,学号:" + s.getStudentId()); |
||||
|
} else if (p instanceof Teacher) { |
||||
|
Teacher t = (Teacher) p; |
||||
|
// 现在Teacher有了getTeacherId(),就不会报错了
|
||||
|
System.out.println(t.getName() + " 是老师,工号:" + t.getTeacherId()); |
||||
|
} else { |
||||
|
System.out.println(p.getName() + " 是普通人员"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
package w5挑战版; |
||||
|
|
||||
|
// 学生
|
||||
|
public class Student extends Person { |
||||
|
private String studentId; // 学号
|
||||
|
|
||||
|
public Student(String name, int age, String studentId) { |
||||
|
super(name, age); |
||||
|
this.studentId = studentId; |
||||
|
} |
||||
|
|
||||
|
// 重写显示信息
|
||||
|
@Override |
||||
|
public void showInfo() { |
||||
|
System.out.printf("【学生】%s | 年龄:%d | 学号:%s%n", getName(), getAge(), studentId); |
||||
|
} |
||||
|
|
||||
|
// 🔥 必须加这个getter!否则PersonManager里调用不到
|
||||
|
public String getStudentId() { |
||||
|
return studentId; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
package w5挑战版; |
||||
|
|
||||
|
// 老师
|
||||
|
public class Teacher extends Person { |
||||
|
private String teacherId; // 工号
|
||||
|
|
||||
|
public Teacher(String name, int age, String teacherId) { |
||||
|
super(name, age); |
||||
|
this.teacherId = teacherId; |
||||
|
} |
||||
|
|
||||
|
// 重写显示信息
|
||||
|
@Override |
||||
|
public void showInfo() { |
||||
|
System.out.printf("【老师】%s | 年龄:%d | 工号:%s%n", getName(), getAge(), teacherId); |
||||
|
} |
||||
|
|
||||
|
// 🔥 必须加这个getter!否则PersonManager里调用不到
|
||||
|
public String getTeacherId() { |
||||
|
return teacherId; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
package w5挑战版; |
||||
|
|
||||
|
|
||||
|
// 测试重构后的系统
|
||||
|
public class TestPersonSystem { |
||||
|
public static void main(String[] args) { |
||||
|
PersonManager manager = new PersonManager(); |
||||
|
|
||||
|
// 统一添加(无需区分学生/老师,全部是Person)
|
||||
|
manager.addPerson(new Student("张三", 18, "2025001")); |
||||
|
manager.addPerson(new Teacher("李老师", 40, "T001")); |
||||
|
manager.addPerson(new Student("李四", 19, "2025002")); |
||||
|
|
||||
|
// 显示所有人
|
||||
|
manager.showAllPersons(); |
||||
|
|
||||
|
// 检查特定属性
|
||||
|
manager.checkPersonDetails(); |
||||
|
} |
||||
|
} |
||||
|
After Width: | Height: | Size: 105 KiB |
@ -0,0 +1,8 @@ |
|||||
|
核心思路:利用多态,将 addStudent 和 addTeacher 合并为 addPerson(Person p),用父类引用统一接收所有子类对象,存入 List<Person> 统一管理,实现代码复用和统一入口。 |
||||
|
2. 特有属性的处理方案: |
||||
|
◦ 方案一(作业首选):instanceof 类型判断 + 向下转型。在需要访问子类特有属性时,通过 instanceof 判断对象的真实类型,将父类引用向下转型为对应的子类类型,再调用子类特有的 getter 方法(如 getStudentId()/getTeacherId()),从而获取特有属性。 |
||||
|
◦ 方案二(进阶):模板方法模式。在父类 Person 中定义抽象方法 getSpecialInfo(),让 Student和 Teacher 各自实现该方法,返回自己的特有属性,父类统一调用该方法,无需类型判断,代码更简洁,符合开闭原则。 |
||||
|
3. 优势: |
||||
|
◦ 合并方法后,减少了代码冗余,统一了人员添加的入口,提升了代码的可维护性。 |
||||
|
◦ 多态保证了新增人员类型(如「管理员」)时,无需修改 addPerson 方法,仅需新增子类即可,符合面向对象的设计思想。 |
||||
|
4. 注意事项:向下转型时,必须先通过 instanceof 判断类型,避免 ClassCastException 类型转换异常;子类特有属性必须通过 getter 方法访问,保证封装性。 |
||||
@ -0,0 +1,18 @@ |
|||||
|
package w5进阶版; |
||||
|
|
||||
|
// 电脑
|
||||
|
public class Computer { |
||||
|
// 使用USB设备的方法(多态参数)
|
||||
|
public void useUSB(USB usb) { |
||||
|
System.out.println("\n电脑开始使用USB设备..."); |
||||
|
usb.open(); |
||||
|
// 模拟工作
|
||||
|
try { |
||||
|
Thread.sleep(500); |
||||
|
} catch (InterruptedException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
usb.close(); |
||||
|
System.out.println("USB设备使用完毕\n"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
package w5进阶版; |
||||
|
|
||||
|
// 键盘
|
||||
|
public class Keyboard implements USB { |
||||
|
@Override |
||||
|
public void open() { |
||||
|
System.out.println("⌨️ 键盘已连接并打开"); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void close() { |
||||
|
System.out.println("⌨️ 键盘已关闭并断开"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
package w5进阶版; |
||||
|
|
||||
|
// 鼠标
|
||||
|
public class Mouse implements USB { |
||||
|
@Override |
||||
|
public void open() { |
||||
|
System.out.println("🖱️ 鼠标已连接并打开"); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void close() { |
||||
|
System.out.println("🖱️ 鼠标已关闭并断开"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
package w5进阶版; |
||||
|
|
||||
|
// 测试
|
||||
|
public class TestUSB { |
||||
|
public static void main(String[] args) { |
||||
|
// 创建电脑对象
|
||||
|
Computer myComputer = new Computer(); |
||||
|
|
||||
|
// 创建USB设备
|
||||
|
USB mouse = new Mouse(); |
||||
|
USB keyboard = new Keyboard(); |
||||
|
|
||||
|
// 插入不同设备
|
||||
|
myComputer.useUSB(mouse); |
||||
|
myComputer.useUSB(keyboard); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
package w5进阶版; |
||||
|
|
||||
|
// USB接口
|
||||
|
public interface USB { |
||||
|
void open(); // 打开设备
|
||||
|
void close(); // 关闭设备
|
||||
|
} |
||||
|
After Width: | Height: | Size: 116 KiB |
Loading…
Reference in new issue