A third solution[2] is to recognize that the RegularGradingStrategy is virtually the same as BasicGradingStrategy. The method getGradePointsFor as defined in HonorsGradingStrategy is basically an extension of the method in RegularGradingStrategyit does what the base class method does, plus a little more. In other words, you can supply a default definition for getGradePointsFor in BasicGradingStrategy that will be extended in HonorsGradingStrategy.
Move the definition for getGradePointsFor from RegularGradingStrategy to BasicGradingStrategy. You should no longer declare BasicGradingStrategy as abstract, since all of its methods supply definitions. // BasicGradingStrategy.java package sis.studentinfo; public class BasicGradingStrategy implements GradingStrategy { public int getGradePointsFor(Student.Grade grade) { return basicGradePointsFor(grade); } int basicGradePointsFor(Student.Grade grade) { switch (grade) { case A: return 4; case B: return 3; case C: return 2; case D: return 1; default: return 0; } } } // RegularGradingStrategy.java package sis.studentinfo; public class RegularGradingStrategy extends BasicGradingStrategy { } RegularGradingStrategy no longer defines any methods! (Compile, test.) Next, change the code in HonorsGradingStrategy to extend the superclass method getGradePointsFor. To extend a method, you define a method with the same name in a subclass. In that subclass method, you call the superclass method to effect its behavior. You supply additional, specialized behavior in the remainder of the subclass method. In comparison to extending, Java will let you fully supplant a method's definition with a completely new one that has nothing to do with the original. This is known as overriding a method. This is a semantic definition: The Java compiler knows no distinction between overriding and extending; it's all overriding to the compiler. You, on the other hand, recognize an extending method by its call to the superclass method of the same name.
Your subclass definition should specialize the behavior of the superclass method in some manner, not change it completely. To explicitly call a method in a superclass, use the super keyword to scope the message send, as shown in bold: package sis.studentinfo; public class HonorsGradingStrategy extends BasicGradingStrategy { public int getGradePointsFor(Student.Grade grade) { int points = super.getGradePointsFor(grade); if (points > 0) points += 1; return points; } } When you use the super keyword, the Java VM looks in the superclass to find the corresponding method definition. |