Java实验5《面向对象——多态》

灰太狼 2021-11-23 00:10 397阅读 0赞

一、实验目的

  1. 理解多态性和动态绑定
  2. 存储、提取和操作ArrayList中的对象

二、实验内容

  1. 【Person、Student、Employee类】(注:此题在书上原题基础上有修改)设计一个名为Person的类和它的两个名为Student和Employee子类。
      每个人都有姓名和电话号码。学生有年级状态(大一、大二、大三或大四)。将这些状态定义为常量。一个雇员有工资和受聘日期。定义一个名为MyDate的类,包含数据域:year(年)、month(月)和day(日)。将各个类的数据域进行封装,并设置合理的读写访问器。
    覆盖每个类中的toString方法,返回类名及相应的类中可以获取的所有信息构成的字符串,如Person类的toString方法返回“Person类:姓名为*** 电话为***”;Student类的toString方法返回“Student类: 姓名为*** 电话为*** 年级为***”。
      在Student和Employee两个类中分别加入displayObject()方法,可以打印出对学生和雇员的提示消息,提示学生“to ***(学生姓名):请按时交实验报告”,提示雇员“to ***(雇员姓名):请按时上班”。
      目标输出任务:

    • 画出这些类的UML图。
    • 实现这些类。
    • 编写一个测试类,
      1)创建方法public static void m1(Person p),显示p的姓名;
      2)创建方法public static void m2(Person p),打印p的toString方法返回的字符串;
      3)创建方法public static void m3(Person p),如果p是Student类或者Employee类的实例,分别调用它们的displayObject();
      4)在主函数中创建Person、Student、Employee的对象实例,将它们均声明为Person类对象。将它们分别传入m1、m2和m3,体会多态。

 1.1 UML图
Alt

 1.2 程序代码:
(1)TestProgram1类的源程序:

  1. //TestProgram1类的源程序
  2. //此测试类用于测试Person类、Student类、Employee类
  3. public class TestProgram1{
  4. public static void main(String[] args){
  5. //在主函数中创建Person、Student、Employee的对象实例,
  6. //将它们均声明为Person类对象。将它们分别传入m1、m2和m3
  7. Person p1 = new Person("Annay", "15269358569");
  8. Person p2 = new Student("大一", "Boens", "14985685962");
  9. Person p3 = new Employee("10万/月", new MyDate("2018", "1", "20") , "Concy", "18659856589");
  10. //将对象p1分别传入方法m1、m2、m3中
  11. m1(p1);
  12. m2(p1);
  13. m3(p1);
  14. //将对象p2分别传入方法m1、m2、m3中
  15. m1(p2);
  16. m2(p2);
  17. m3(p2);
  18. //将对象p3分别传入方法m1、m2、m3中
  19. m1(p3);
  20. m2(p3);
  21. m3(p3);
  22. }//mian方法结束
  23. //显示p的姓名
  24. public static void m1(Person p){
  25. System.out.println( p.getName() );
  26. }//m1结束
  27. //打印p的toString方法返回的字符串
  28. public static void m2(Person p){
  29. System.out.println( p.toString() );
  30. }//m2结束
  31. //如果p是Student类或者Employee类的实例,分别调用它们//的displayObject()
  32. public static void m3(Person p){
  33. if(p instanceof Student)
  34. ((Student)p).displayObject();
  35. else if(p instanceof Employee)
  36. ((Employee)p).displayObject();
  37. }//m3结束
  38. }//TestClass结束

(2)Person类的源程序:

  1. //Person类的源程序
  2. public class Person {
  3. private String name;
  4. private String numbers;
  5. public Person(){
  6. }
  7. public Person(String name, String numbers){
  8. this.name = name;
  9. this.numbers = numbers;
  10. }
  11. public String getName(){
  12. return name;
  13. }
  14. public String getNumbers(){
  15. return numbers;
  16. }
  17. public void setName(String name){
  18. this.name = name;
  19. }
  20. public void setNumbers(String numbers){
  21. this.numbers = numbers;
  22. }
  23. public String toString(){
  24. return "Person类:姓名为" + name + " 电话为" + numbers;
  25. }
  26. }

(3)Student类的源程序:

  1. //Student类的源程序
  2. public class Student extends Person{
  3. private String status;
  4. public Student(){
  5. }
  6. public Student(String status, String name, String numbers){
  7. super(name, numbers);
  8. this.status = status;
  9. }
  10. public String getStatus(){
  11. return status;
  12. }
  13. public void setStatus(String status){
  14. this.status = status;
  15. }
  16. public void displayObject(){
  17. System.out.println("to " + super.getName() + ":请按时交实验报告");
  18. }
  19. public String toString(){
  20. return "Student类:姓名为" + super.getName() + " 电话为"
  21. + super.getNumbers() + " 年级为" + status;
  22. }
  23. }

(4)Employee类的源程序:

  1. //Employee类的源程序
  2. public class Employee extends Person {
  3. private String salary;
  4. private MyDate dateOfEmployment=new MyDate();
  5. public Employee(){
  6. }
  7. public Employee(String salary,MyDate dateOfEmployment,String name,String numbers){
  8. super(name,numbers);
  9. this.salary = salary;
  10. this.dateOfEmployment = dateOfEmployment;
  11. }
  12. public String getSalary(){
  13. return salary;
  14. }
  15. public void setSalary(String salary){
  16. this.salary = salary;
  17. }
  18. public MyDate getDateOfEmployment(){
  19. return dateOfEmployment;
  20. }
  21. public void setDateOfEmployment(MyDate dateOfEmployment){
  22. this.dateOfEmployment = dateOfEmployment;
  23. }
  24. public void displayObject(){
  25. System.out.println("to "+ super.getName() + ": 请按时上班");
  26. }
  27. public String toString(){
  28. return "Employee类:姓名为" + super.getName()
  29. + " 电话为" + super.getNumbers() + " 工资为" + salary;
  30. }
  31. }

(5)MyDate类的源程序:

  1. //MyDate类的源程序:
  2. public class MyDate{
  3. private String year;
  4. private String month;
  5. private String day;
  6. public MyDate(){
  7. }
  8. public MyDate(String year, String month, String day){
  9. this.year = year;
  10. this.month = month;
  11. this.day = day;
  12. }
  13. public String getYear(){
  14. return year;
  15. }
  16. public String getMonth(){
  17. return month;
  18. }
  19. public String getDay(){
  20. return day;
  21. }
  22. public void setYear(){
  23. this.year = year;
  24. }
  25. public void setMonth(String month){
  26. this.month = month;
  27. }
  28. public void setDay(String day){
  29. this.day = day;
  30. }
  31. }

  1.3 运行结果与分析:
Alt
    运行正确,符合题目要求。创建三个类的实例,三个测试方法,每个实例都用三个方法测试。

  1.4 心得体会:
    此题主要是三个类之间的继承与多态关系应用,先画UML图再一次性写出三个类,当然还有额外的MyDate类,最后再写测试类,测试类中的方法调用需谨慎书写。这道题的难点在于不同类之间的方法与对象的调用,类的声明类型与实际类型的应用。


  1. (P380, 11.5)【课程类Course】改写程序清单10-6中的Course类。 使用ArrayList代替数组来存储学生。不应该改变Course类的原始合约 (即不要改变构造方法和方法的方法头定义,包括返回类型、方法名及参数列表,但私有的成员可以改变)。

    //程序清单10-6
    public class Course {
    private String courseName;
    private String[] students = new String[100];
    private int numberOfStudents;

    public Course(String courseName) {

    1. this.courseName = courseName;

    }

    public void addStudent(String student) {

    1. students[numberOfStudents] = student;
    2. numberOfStudents++;

    }

    public String[] getStudents() {

    1. return students;

    }

    public int getNumberOfStudents() {

    1. return numberOfStudents;

    }

    public String getCourseName() {

    1. return courseName;

    }

    public void dropStudent(String student) {

    1. // Left as an exercise in Exercise 9.9

    }
    }

    //程序清单10-5
    //【注意:请参考以下程序来测试Course类,同时注意在此段程序基础上,增加必要的代码,以完整地测试Course类中定义的所有方法】
    public class TestCourse {
    public static void main(String[] args) {

    1. Course course1 = new Course("Data Structures");
    2. Course course2 = new Course("Database Systems");
    3. course1.addStudent("Peter Jones");
    4. course1.addStudent("Brian Smith");
    5. course1.addStudent("Anne Kennedy");
    6. course2.addStudent("Peter Jones");
    7. course2.addStudent("Steve Smith");
    8. System.out.println("Number of students in course1: "
    9. + course1.getNumberOfStudents());
    10. String[] students = course1.getStudents();
    11. for (int i = 0; i < course1.getNumberOfStudents(); i++)
    12. System.out.print(students[i] + ", ");
    13. System.out.println();
    14. System.out.print("Number of students in course2: "
    15. + course2.getNumberOfStudents());

    }
    }

 2.1 程序代码:
(1)Course类

  1. //Course类
  2. import java.util.ArrayList;
  3. public class Course {
  4. private String courseName;
  5. private ArrayList<String> students = new ArrayList<>();
  6. public Course(String courseName) {
  7. this.courseName = courseName;
  8. }
  9. //添加学生
  10. public void addStudent(String student) {
  11. students.add(student);
  12. }
  13. //输出学生姓名
  14. public String[] getStudents() {
  15. int size = students.size();
  16. String[] st = new String[size];
  17. for(int i=0; i<students.size(); i++)
  18. st[i] = students.get(i);
  19. return st;
  20. }
  21. //返回数组大小
  22. public int getNumberOfStudents() {
  23. return students.size();
  24. }
  25. //返回课程名称
  26. public String getCourseName() {
  27. return courseName;
  28. }
  29. //删除学生
  30. public void dropStudent(String student) {
  31. students.remove(student);
  32. }
  33. }

(2)TestCourse类

  1. //TestCourse类
  2. public class TestCourse {
  3. public static void main(String[] args) {
  4. Course course1 = new Course("Data Structures");
  5. Course course2 = new Course("Database Systems");
  6. //输入coures1,course2的学生名字
  7. course1.addStudent("Peter Jones");
  8. course1.addStudent("Brian Smith");
  9. course1.addStudent("Anne Kennedy");
  10. course2.addStudent("Peter Jones");
  11. course2.addStudent("Steve Smith");
  12. //输出course1的名称
  13. System.out.println("course1: " + course1.getCourseName());
  14. //输出course1的学生数量
  15. System.out.println("Number of students in course1: "
  16. + course1.getNumberOfStudents());
  17. //输出course1的学生名字
  18. String[] st1 = course1.getStudents();
  19. for (int i = 0; i < course1.getNumberOfStudents(); i++)
  20. System.out.print(st1[i] + ", ");
  21. System.out.println();
  22. System.out.println();
  23. System.out.println("After coures1 removes \"Peter Jones\" ");
  24. //删除courese1中的“Peter Jones”
  25. course1.dropStudent("Peter Jones");
  26. //输出删除后course1的学生数量
  27. System.out.println("Number of students in course1: "
  28. + course1.getNumberOfStudents());
  29. //输出删除后course1的学生名字
  30. String[] st3 = course1.getStudents();
  31. for (int i = 0; i < course1.getNumberOfStudents(); i++)
  32. System.out.print(st3[i] + ", ");
  33. System.out.println();
  34. System.out.println();
  35. //输出course2的名称
  36. System.out.println("course2: " + course2.getCourseName());
  37. //输出course2的学生数量
  38. System.out.println("Number of students in course2: "
  39. + course2.getNumberOfStudents());
  40. //输出course2的学生名字
  41. String[] st2 = course2.getStudents();
  42. for (int i = 0; i < course2.getNumberOfStudents(); i++)
  43. System.out.print(st2[i] + ", ");
  44. System.out.println();
  45. System.out.println();
  46. System.out.println("After coures2 removes \"Steve Smith\" ");
  47. //删除courese2中的“Steve Smith”
  48. course2.dropStudent("Steve Smith");
  49. //输出删除后course2的学生数量
  50. System.out.println("Number of students in course2: "
  51. + course2.getNumberOfStudents());
  52. //输出删除后course2的学生名字
  53. String[] st4 = course2.getStudents();
  54. for (int i = 0; i < course2.getNumberOfStudents(); i++)
  55. System.out.print(st4[i] + ", ");
  56. System.out.println();
  57. }
  58. }

  2.2 运行结果:
Alt

  2.3 心得体会:
    此题主要是ArrayList类中的方法的调用与运用,再就是测试时运用所有已创建的方法以及调整输出格式。


  1. 附加题(可选做)(P381, 11.10)(利用继承实现MyStack)在程序清单11-10中,MyStack是用组合实现的。扩展ArrayList创建一个新的栈类。实现MyStack类。编写一个测试程序,提示用户输入5个字符串,然后以逆序显示这些字符串。

  3.1 程序代码:

  1. import java.util.Scanner;
  2. public class MyStack extends java.util.ArrayList{
  3. public MyStack(){
  4. }
  5. //实现获取栈的最后一个元素
  6. public Object peek(){
  7. return this.get(this.size()-1);
  8. }
  9. //创建栈的实例并把栈的最后一个元素传给实例对象,然后删除这个元素
  10. public Object pop(){
  11. Object o = this.get(this.size()-1);
  12. this.remove(this.size() - 1);
  13. return o;
  14. }
  15. //将这个实例对象放入一个新的栈中
  16. public void push(Object o){
  17. this.add(o);
  18. }
  19. //测试程序
  20. @SuppressWarnings("unchecked")
  21. public static void main(String[] args){
  22. Scanner input = new Scanner(System.in);
  23. System.out.println("请输入5个字符串: ");
  24. MyStack mystack = new MyStack();
  25. for(int i = 0; i < 5; i++) {
  26. String st = input.next();
  27. mystack.push(st);
  28. }
  29. System.out.println("逆序输出为: ");
  30. for(int i=0; i<5; i++)
  31. System.out.print(mystack.pop() + " ");
  32. System.out.println();
  33. }//main方法结束
  34. }//MyStack类结束

  3.2 运行结果及分析:
Alt
  运行结果正确,输入5个字符串,利用MyStack逆序输出,但是编译时出现了一个小问题,不过不影响运行,具体说明见下。

  3.3 心得体会:
  本题利用继承关系,创建MyStack继承类,关键在于思路。想清楚继承类中需要书写的方法,其实就三个,取栈的最后一个元素、取栈的最后一个元素再删除、向栈里面添加元素。再就是这三个方法的书写,直接使用泛型,调用时采用类似this.get()的方式调用就好。
  本题遗留了一个小问题:
Alt
  程序编译显示以上错误,后经过检查是使用泛型时需要确定类型的问题,其中一种解决方法是添加注释:@SuppressWarnings(“unchecked”)
  但是,貌似由于版本问题,问题依旧存在。
  还有一个解决方法是泛型具体化,不过此方法在本题中不方便使用,所以问题暂未解决。


发表评论

表情:
评论列表 (有 0 条评论,397人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java面向对象

    1、 认识多态 (1)多态一词的通常含义是指能够呈现出多种不同的形式或形态。 (2)在程序设计的术语中,它意味着一个特定类型的变量可以引用不同类型的对象,并且自动地

    相关 面向对象

    面向对象—多态 定义 实现 原理 1、定义 > 多态可以简单的概括为“一个接口,多种方法”,在程序运行过程中才决定调用的函数,简单的说就是,允许

    相关 面向对象

    多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。 编译时的多态性: 编译时的多态性是通过重

    相关 面向对象---

    多态: > 可以理解为事物存在的多种体现形态。 > 比如:人:男人,女人 多态的体现: > 父类的引用指向了自己的子类对象。 > > 父类的引用也可以接受自己的对象。