Previously on OOP:
The last three requirements in Phonebook are: (1), convert the first Contact into a String; (2), convert the Contact of a given position to a String; (3), convert the entire phone book to a String.
在开始做第二项大作业University Management System之前,本黄鸭要提一下和考试有关的事情:
(1)考试题目一般有6个段落的requirements,比大作业要多。
(2)做完一个段落的requirements,可以运行一下main函数,也可以全部编完一起运行。但是编译要经常做,因为要是编译不过,直接挂科。
(3)必须按照题目顺序做,因为JUnit test会在第一个失败的test case处停下来。
(4)添加新的classes必须是适当的,不能乱增加。
(5)最好所有attributes都是private的。假如全设置为public的,直接挂科。
(6)必须使用面向对象的编程,而不是面向过程的编程。
这是需求/题目的第一段话,里面没有什么有效的信息。所以,我们认为主的类是和这个project同名的University,大部分的代码都在这个类里面编写。
有点像在讲University类是主的类。另外还讲了构造函数接收的参数是大学的名称,那么,在attributes部分中,必有一个字符串类型的变量用于存放大学名称。
大学名称的变量是私有的,通过getName() getter才能访问。
不仅大学要有名字,校长的姓名也要记录下来。可以在attributes中声明两个私有的、字符串类型的变量,分别存放校长的姓氏和名字。设置这两个变量的值要通过setRector() setter。
访问私有变量要通过getRector() getter。这个函数的返回值是一个字符串,里面有校长的姓氏和名字,当中用逗号分隔。因为只涉及到两个字符串和一个空格字符,没必要用StringBuffer,直接在return关键字的后面,用“+”把它们concatenate在一起就好了。
enroll()函数接收的参数是学生的姓氏和名字,返回学生的学号。
首先,一个大学只有一名校长,但是却可以有好多学生。要是后面还有针对学生群体的requirements,那么我们这里enroll的每一名学生,都要记录在数组,或者某种数据结构中。
其次,学生信息至少包含姓氏、名字和学号。如果想要存放在数组中,数组必须是二维的,第一个维度存放指针,指向学生信息的指针。由此可见,最好新创建一个类,叫Student,把学生信息存放在里面,然后数组中存放Student类型的object references即可。
最后,创建Student类的实例必须在生成学号之后。所以请各位宝宝们现在先不要编写代码,看一下学号是怎么分配的。
学号从10000开始,按照入学顺序依次累加。也就是说,数组中第零号学生的学号应该是10000,数组中第一号学生的学号是10001,以此类推。用数学归纳法可以看出:
在声明数组时,大小写1000。
给定学号,想要查询学生信息,那么我们应该先把学号转化为数组下标:
然后使用数组下标取出数组中的object reference of type Student。最后可以在Student类中定义一个toString()函数,把学生信息转化为字符串。
现在attributes里面存放的是学号,如果换成数组的下标,也是可以的。
这个需求和requirement 2基本完全相同。
我们把每门课程的信息存放到Course类中,然后再在University类中创建一个存放所有课程的数组。
课程编号和数组下标之间也有关系:
在University类的attributes里面,需要存放的是数组下标,或者课程编号。
在声明数组时,大小写50。
先使用数组下标取出object reference of type Course,再调用Course类中新增的toString()函数。
做完requirement 3,我们有课程和学生,现在学生要参加课程的学习,即把学生加入到课程中,也就是在Course类里面建立一个数组,存放参加这门课程的Student的object references。
Course类中存放学生信息的数组,在声明时,大小写100。重点看一下后半句话,一名学生最多只能上25门课程,这说明了什么?说明不仅要把学生加入到课程中,还要把课程加入到学生中,即Student类中有一个存放课程信息的数组,这个数组在声明时的大小是25。
listAttendees()函数只需要返回存放学生信息的数组就可以了。
把存放学生信息的数组转化为字符串。在循环结构中,先把每个数组元素用toString()函数转化为字符串,然后在每个数组元素后面加上一个回车符。
和requirement 4.4相同,而且从侧面说明了确实有必要在Student类中声明一个存放课程信息的数组。
另外,如果没有设这个数组,我们只能遍历University类的existCourses数组。用每一个Course类的object reference调用listAttendees()函数,看里面有没有给定学生的信息。如果有,那么就把这门课程加入到返回值里面;如果没有,就不要加。
绿色的两行代码调用了University class中刚刚定义好的函数。
红色的两行代码分别是:
(1)把这门课程的信息加到对应学生中
在把课程信息添加进数组时,我们需要遍历数组,当找到第一个空置的位置时,就把Course object reference存放进去。用attendCourses.length行不行呢?答案是不行,因为attendCourses.length恒等于25。
还有一种做法是在attributes部分声明一个存放当前数组下标的变量。
(2)把这名学生的信息加到对应课程中
“String print = "\n";”这行代码是字符串的初始化,必须有。
“attendCourses[index]”的前后都是表示concatenation的加号,所以编译器会自动调用toString()函数,把Course类的object reference转化为String类型。
虽然这里使用的是String,但是由于参加课程的学生比较多,所以推荐使用StringBuffer的append()函数。
欢迎使用本黄鸭编写的小程序~
微信公众号二维码:
领取专属 10元无门槛券
私享最新 技术干货