/* --- CSU213 Spring 2006 Lecture Notes --------- Copyright 2006 Viera K. Proulx Lecture 6: Help! Goals: - learn to define and use methods in classes with containment - learn to compare two instances for extensional equality Introduction: Let us return to defining methods for the class of data that represents grade records. However, we use the class definition that used a separate class to represent the course, so that several students can get a grade in the same course. Here are the classes that represents grade records and courses: +---------------+ | GradeRecord | +---------------+ +-----------------| Course course | | | String term | | | double grade | | +---------------+ v +---------------+ | Course | +---------------+ | int num | | String title | | int credits | +---------------+ We changed the data a bit: the Course class knows the course number and the course title as well as the number of credits the course carreis. The student's grade record records the course, the grade earned, and the term in which the student took the course (for now, a String, such as "SP06" or "FL05" --- later, we may replace that with a class that represents the term information.) We need new examples of grade records (and courses as well): Course fund = new Course(211, "Fundamentals", 4); Course ovw = new Course(220, "Overview", 1); Course algo = new Course(690, "Algorithms", 4); GradeRecord fundFL05 = new GradeRecord(fund, "FL05", 3.66); GradeRecord ovwFL05 = new GradeRecord(ovw, "FL05", 4.0); GradeRecord algoSP05 = new GradeRecord(algo, "SP05", 3.0); Again, we want to compute the quality points the students earned in a course on the in the grade record. The method remains in the class GradeRecord and its purpose and header are unchanged: // compute the quality points for this grade record double qPoints(){ ... } We need new examples.(We again use the method almpstDouble we defined in the previous lecture.) // determine whether two double values are almost the same boolean almostSame(double d1, double d2, double eps) { return ((d1 - d2) * (d1 -d2) < eps); } boolean test1 = this.almostSame(this.fundFL05.qPoints(), 14.64, 0.01); boolean test2 = this.almostSame(this.ovwFL05.qPoints(), 4.0, 0.01); boolean test3 = this.almostSame(this.algoSP05.qPoints(), 12.0, 0.01); Well, the method will change, but the examples are the same!!! This is a good way to design programs - we refine the class definitions, and the method implementations, but the program behavior is the same. The next step is the template for the methods in this class: ... this.course ... -- of the type Course ... this.term ... -- of the type String ... this.grade ... -- of the type double Well, with that information we cannot compute the quality points. We know the grade, but only the instance of the Course that we refer to knows about the credits. That means, we delegate this task to the class Course. Of course, we have to pass on the information about the earned grade that we already know. The method header and the purpose statement for method qPoints in the class Course will be: // compute the quality points for the given grade earned in this course double qPoints(double grade){ ... } Once we have the header and the purpose statement for this method, we can finish designing the original qPoints method in the class GradeRecord.We first add to the template the fact that this.course can invoke the method qPoints: ... this.course.qPoints(double g) ... -- of the type double and the body of the method in the class GradeRecord becomes: // compute the quality points for this grade record double qPoints(){ return this.course.qPoints(this.grade); } We now complete the design of the method qPoints for the class Course. Of course, we first need more examples: boolean test4 = this.almostSame(this.fund.qPoints(3.66), 14.64, 0.01); boolean test5 = this.almostSame(this.ovw.qPoints(4.0), 4.0, 0.01); boolean test6 = this.almostSame(this.algo.qPoints(3.0), 12.0, 0.01); The template for the methods in the class Course is: ... this.num ... ... this.title ... ... this.credits ... The method body is now easy: // compute the quality points for the given grade earned in this course double qPoints(double grade){ return this.credits * grade; } We can now run the tests for both methods. Work out the design of the method that determines whether a course on the grade record in the transcript is an OK course, i.e. has a course number above the given level. Make sure you follow the design recipe. */ /* +---------------+ | GradeRecord | +---------------+ +-----------------| Course course | | | String term | | | double grade | | +---------------+ v +---------------+ | Course | +---------------+ | int num | | String title | | int credits | +---------------+ */ // to represent a grade record on a transcript class GradeRecord { Course course; String term; double grade; GradeRecord(Course course, String term, double grade){ this.course = course; this.term = term; this.grade = grade; } /* TEMPLATE: ... this.course ... -- of the type Course ... this.term ... -- of the type String ... this.grade ... -- of the type double ... this.course.qPoints(double g) ... -- of the type double */ // compute the quality points for this grade record double qPoints(){ return this.course.qPoints(this.grade); } } // to represent a course information class Course { int num; String title; int credits; Course(int num, String title, int credits) { this.num = num; this.title = title; this.credits = credits; } /* TEMPLATE: ... this.num ... -- of the type int ... this.title ... -- of the type String ... this.credits ... -- of the type int */ // compute the quality points for the given grade earned in this course double qPoints(double grade){ return this.credits * grade; } } class ExamplesGRC{ ExamplesGRC() {} Course fund = new Course(211, "Fundamentals", 4); Course ovw = new Course(220, "Overview", 1); Course algo = new Course(690, "Algorithms", 4); GradeRecord fundFL05 = new GradeRecord(this.fund, "FL05", 3.66); GradeRecord ovwFL05 = new GradeRecord(this.ovw, "FL05", 4.0); GradeRecord algoSP05 = new GradeRecord(this.algo, "SP05", 3.0); // determine whether two double values are almost the same boolean almostSame(double d1, double d2, double eps) { return ((d1 - d2) * (d1 -d2) < eps); } boolean test1 = this.almostSame(this.fundFL05.qPoints(), 14.64, 0.01); boolean test2 = this.almostSame(this.ovwFL05.qPoints(), 4.0, 0.01); boolean test3 = this.almostSame(this.algoSP05.qPoints(), 12.0, 0.01); boolean test4 = this.almostSame(this.fund.qPoints(3.66), 14.64, 0.01); boolean test5 = this.almostSame(this.ovw.qPoints(4.0), 4.0, 0.01); boolean test6 = this.almostSame(this.algo.qPoints(3.0), 12.0, 0.01); }