一、实验目的
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,体会多态。
2. 【课程类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) {
this.courseName = courseName;
}
public void addStudent(String student) {
students[numberOfStudents] = student;
numberOfStudents++;
}
public String[] getStudents() {
return students;
}
public int getNumberOfStudents() {
return numberOfStudents;
}
public String getCourseName() {
return courseName;
}
public void dropStudent(String student) {
// Left as an exercise in Exercise 9.9
}
}
程序清单10-5
【注意:请参考以下程序来测试Course类,同时注意在此段程序基础上,增加必要的代码,以完整地测试Course类中定义的所有方法】
public class TestCourse {
public static void main(String[] args) {
Course course1 = new Course("Data Structures");
Course course2 = new Course("Database Systems");
course1.addStudent("Peter Jones");
course1.addStudent("Brian Smith");
course1.addStudent("Anne Kennedy");
course2.addStudent("Peter Jones");
course2.addStudent("Steve Smith");
System.out.println("Number of students in course1: "
+ course1.getNumberOfStudents());
String[] students = course1.getStudents();
for (int i = 0; i < course1.getNumberOfStudents(); i++)
System.out.print(students[i] + ", ");
System.out.println();
System.out.print("Number of students in course2: "
+ course2.getNumberOfStudents());
}
}
3. 附加题(可选做)(利用继承实现MyStack)在程序清单11-10中,MyStack是用组合实现的。扩展ArrayList创建一个新的栈类。实现MyStack类。编写一个测试程序,提示用户输入5个字符串,然后以逆序显示这些字符串。
三、实验要求:
要求每个学生独立完成实验任务。
四、实验报告
1. 实验结果与分析
(1) Person、Student、Employee类
A) UML类图
B) 实验运行过程
C) 结果分析
本题分成五个类:
Person类中含最起初name和telenum的属性,设置其get和set方法,定义toString函数;
Student类继承Person类,同时加入Grade属性,设置其get和set方法,定义toString函数和displayObject函数;
Employee类继承Person类,同时加入salary和MyDate类型的date属性,设置其get和set方法,定义toString函数和displayObject函数;
MyDate类是date的类型定义,其中包括year,month,day属性,设置其get和set方法,在有参构造方法中设置属性的值(利于主函数的参数设置);
Test类是主函数的定义类,其中首先定义年级信息的常量,便于主函数的引用,然后定义m1,m2,m3函数,其中m3函数需要判断实例类型,需要使用强制转换才能调用Student类或Employee类中的displayObject方法,判断实例类型时选择使用instanceof关键词。
主函数中首先定义三个不同类型的实例,并引用给都是Person类型的变量,然后定义其name和telenum,其中Student实例需要强制转换后定义其Grade值,Employee实例需要强制转换后定义其salary值和date值,date是一个新创建的MyDate类型的对象。
接着调用三个实例的m1,m2,m3方法即可输出结果。
(2)Course类
A) UML类图
B) 实验运行过程
C) 实验结果分析
本题只要求将数组相关语句换成我们需要的ArrayList语句即可
因此我们可以直接将语句替换
public class Course {
private String courseName;
private String[] students = new String[100];
//这里更换成
private ArrayList<String> students = new ArrayList<String>(100);
private int numberOfStudents;
public Course(String courseName) {
this.courseName = courseName;
}
public void addStudent(String student) {
students[numberOfStudents] = student;
//这里更换成
students.add(numberOfStudents,student);
其中add(index,o)方法定义是在index下标确定的位置加入o元素
numberOfStudents++;
}
public String[] getStudents() {
//这里更换成
public ArrayList<String> getStudents() {
return students;
}
public int getNumberOfStudents() {
return numberOfStudents;
}
public String getCourseName() {
return courseName;
}
public void dropStudent(String student) {
// Left as an exercise in Exercise 9.9
}
}
【注意:请参考以下程序来测试Course类,同时注意在此段程序基础上,增加必要的代码,以完整地测试Course类中定义的所有方法】
public class TestCourse {
public static void main(String[] args) {
Course course1 = new Course("Data Structures");
Course course2 = new Course("Database Systems");
course1.addStudent("Peter Jones");
course1.addStudent("Brian Smith");
course1.addStudent("Anne Kennedy");
course2.addStudent("Peter Jones");
course2.addStudent("Steve Smith");
System.out.println("Number of students in course1: "
+ course1.getNumberOfStudents());
String[] students = course1.getStudents();
//这里更换成
ArrayList<String>students = course1.getStudents();
for (int i = 0; i < course1.getNumberOfStudents(); i++)
System.out.print(students[i] + ", ");
//这里更换成
students.get(i)
其中get(index)方法返回index下表位置的元素
System.out.println();
System.out.print("Number of students in course2: "
+ course2.getNumberOfStudents());
}
}
(3)MyStack类
A) UML类图
B) 实验运行过程
首先根据提示输入元素个数
再根据提示输入该个数个元素
回车,返回逆序结果
C) 实验结果分析
首先我们分析MyStack和泛类ArrayList的不同:
MyStack需要在栈尾插入,栈尾删除,而ArrayList可以在任意确定位置下进行这样的操作;
调用F3我们可以找到ArrayList类的一些定义
这样就可以想到:我们可以利用ArrayList中已有的add(无参)函数和remove(有参)方法来改写定义,其中add不动,换成push头名,remove的参数设置成this.size()-1来每次删除末尾元素并保存到变量中,这样就实现了本题中必要的入栈出栈操作。
在主函数中,我们首先输入元素个数,再根据元素个数确定循环次数,输入元素,入栈,再循环相同次出栈输出即可
2. 心得体会
本次是练习新学的多态和动态绑定知识点,并对ArrayList列表了解,尤其是第一道题,在进行相关的建构时对MyDate类的实例创建遇到了难处,在一遍遍研究中通过之后,我感觉自己对动态绑定在多态中的理解有了十分显著的提高;而在第二题和第三题过程中对继承相关的应用也进行了巩固
本次实验就我自身而言是不简单的一次,但不简单也代表着有了新的挑战,希望之后的实验能对Java的应用有更显著的提高。
3.源程序
(1)
Person.java
package exp5;
public class Person {
private String name;
private String telenum;
public String getName(){
return this.name;
}
public String getTeleNum(){
return this.telenum;
}
public void setName(String name){
this.name = name;
}
public void setTeleNum(String telenum){
this.telenum = telenum;
}
@Override
public String toString() {
return "Person类:姓名为" + this.getName() + " " + "电话为:" + this.getTeleNum();
}
}
Student.java
package exp5;
public class Student extends Person{
private String Grade;
public String getGrade(){
return Grade;
}
public void setGrade(String Grade){
this.Grade = Grade;
}
@Override
public String toString() {
return "Student类:姓名为" + this.getName() + " " + "电话为:" + this.getTeleNum() + " 年级为:" + this.getGrade();
}
public String displayObject(){
return "to " + this.getName() + ": 请按时交实验报告";
}
}
Employee.java
package exp5;
import java.sql.Date;
public class Employee extends Person{
private int salary;
private MyDate date;
public int getSalary(){
return salary;
}
public void setSalary(int salary){
this.salary = salary;
}
public String getDate(){
return date.getYear() + "," + date.getMonth() + "," + date.getDay();
}
public void setDate(MyDate date){
this.date = date;
}
@Override
public String toString() {
return "Employee类:姓名为" + this.getName() + " " + "电话为:" + this.getTeleNum() + " 工资为:"
+ this.getSalary() + " 受聘日期为:" + this.date.getDate() ;
}
public String displayObject(){
return "to " + this.getName() + ": 请按时上班";
}
}
MyDate.java
package exp5;
public class MyDate {
public MyDate(String year,String month,String day){
this.year = year;
this.month = month;
this.day = day;
}
private String year;
private String month;
private String day;
public String getYear() {
return year;
}
public String getMonth() {
return month;
}
public String getDay() {
return day;
}
public void setYear(String year) {
this.year = year;
}
public void setMonth(String month) {
this.month = month;
}
public void setDay(String day) {
this.day = day;
}
public String getDate(){
return this.year + this.month + this.day;
}
}
Test.java
package exp5;
public class Test {
static final String GradeOne = "One";
static final String GradeTwo = "Two";
static final String GradeThree = "Three";
static final String GradeFour = "Four";
public static void m1(Person p){
System.out.println(p.getName());
}
public static void m2(Person p){
System.out.println(p.toString());
}
public static void m3(Person p){
if(p instanceof Student){
System.out.println(((Student)p).displayObject());
}
else if(p instanceof Employee){
System.out.println(((Employee)p).displayObject());
}
else {
System.out.println("请求有误,请重新尝试!");
}
}
public static void main(String[] args) {
Person aPerson = new Person();
aPerson.setName("a");
aPerson.setTeleNum("12345");
Person bStudent = new Student();
bStudent.setName("b");
bStudent.setTeleNum("67890");
((Student)bStudent).setGrade(GradeOne);
Person cEmployee = new Employee();
cEmployee.setName("c");
cEmployee.setTeleNum("13579");
((Employee) cEmployee).setSalary(15000);
Employee employee = new Employee();
MyDate date = new MyDate("2011","09","05");
((Employee) cEmployee).setDate(date);
m1(aPerson);
m1(bStudent);
m1(cEmployee);
m2(aPerson);
m2(bStudent);
m2(cEmployee);
m3(aPerson);
m3(bStudent);
m3(cEmployee);
}
}
(2)
Course.java
package exp5;
import java.util.ArrayList;
public class Course {
private String courseName;
private ArrayList<String> students = new ArrayList<String>(100);
private int numberOfStudents;
public Course(String courseName) {
this.courseName = courseName;
}
public void addStudent(String student) {
students.add(numberOfStudents,student);
numberOfStudents++;
}
public ArrayList<String> getStudents() {
return students;
}
public int getNumberOfStudents() {
return numberOfStudents;
}
public String getCourseName() {
return courseName;
}
}
TestCourse.java
package exp5;
import java.util.ArrayList;
public class TestCourse {
public static void main(String[] args) {
Course course1 = new Course("Data Structures");
Course course2 = new Course("Database Systems");
course1.addStudent("Peter Jones");
course1.addStudent("Brian Smith");
course1.addStudent("Anne Kennedy");
course2.addStudent("Peter Jones");
course2.addStudent("Steve Smith");
System.out.println("Number of students in course1: "
+ course1.getNumberOfStudents());
ArrayList<String>students = course1.getStudents();
for (int i = 0; i < course1.getNumberOfStudents(); i++)
System.out.print(students.get(i) + ", ");
System.out.println();
System.out.print("Number of students in course2: "
+ course2.getNumberOfStudents());
}
}
(3)
MyStack.java
package exp5;
import java.util.ArrayList;
import java.util.Scanner;
public class MyStack extends ArrayList{
public void push(Object o){
this.add(o);
}
public Object pop(){
Object o = this.get(this.size() - 1);
this.remove(this.size() - 1);
return o;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num;
System.out.println("请输入元素的个数");
num = input.nextInt();
System.out.println("请输入元素: ");
MyStack myStack = new MyStack();
for(int i = 0; i < num;i++){
myStack.push(input.next());
}
for(int i = 0; i < num;i++){
System.out.println(myStack.pop());
}
}
}