// Hypothetical Book class
class Book {
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
public String getTitle() {
return title;
}
public double getPrice() {
return price;
}
public String getBookInfo() {
return title + "-" + price;
}
}
// Your Textbook class
public class Textbook extends Book {
// Instance variable for the edition of the textbook
private int edition;
// Constructor
public Textbook(String title, double price, int edition) {
super(title, price); // Calling the constructor of the superclass (Book)
this.edition = edition;
}
// Method to get the edition of the textbook
public int getEdition() {
return edition;
}
// Overriding the getBookInfo method from the Book class
@Override
public String getBookInfo() {
return super.getBookInfo() + "-" + edition; // Using the superclass's method and adding the edition
}
// Method to check if the current textbook can substitute another
public boolean canSubstituteFor(Textbook other) {
return this.getTitle().equals(other.getTitle()) && this.edition >= other.edition;
}
// Main method (Entry point of the program)
public static void main(String[] args) {
// Create a new Textbook object
Textbook myTextbook = new Textbook("Math 101", 50.0, 3);
// Create another Textbook object to compare
Textbook otherTextbook = new Textbook("Math 101", 40.0, 2);
// Display the book info
System.out.println("My textbook info: " + myTextbook.getBookInfo());
// Check if myTextbook can substitute for otherTextbook
boolean canSubstitute = myTextbook.canSubstituteFor(otherTextbook);
System.out.println("Can my textbook substitute for the other? " + canSubstitute);
}
}
Breakdown
Understanding the Problem Statement: The first step was to understand the requirements. The Textbook class is a subclass of Book and has an additional attribute, edition. The getBookInfo method needs to be overridden to include the edition, and a new method canSubstituteFor is to be added.
Mistake 1: Initially, I thought of adding the title and price attributes to the Textbook class. However, this would be redundant since these attributes are already present in the Book class.
Correction: I used the super keyword to call the constructor of the Book class and set the title and price attributes. This ensures that the Textbook class inherits these attributes from its superclass.
Mistake 2: For the getBookInfo method, I initially thought of rewriting the entire method in the Textbook class.
Correction: Instead of rewriting, I used the super.getBookInfo() method to get the book information from the superclass and then appended the edition information. This approach is more efficient and avoids code duplication.
Mistake 3: For the canSubstituteFor method, I initially missed checking if the titles of the two textbooks are the same.
Correction: I added a condition to check if the titles of the two textbooks are the same using the getTitle() method from the Book class.
Comparing official CB Solution
Overriding getBookInfo Method:
In your solution, you used the @Override annotation before the getBookInfo method, indicating that you’re intentionally overriding a method from the superclass.
College Board’s solution does not use the @Override annotation. While the method will still override the superclass method, the annotation is a good practice because it makes the intention clear and allows the compiler to catch errors if the superclass method signature changes.
Parameter Naming:
- In the canSubstituteFor method, you named the parameter other, while CollegeBoard named it otherTextbook. Both are descriptive, but your friend’s version is slightly more explicit about the type of object expected.
Method Calls in canSubstituteFor:
-
In the canSubstituteFor method, your solution directly accesses the edition instance variable of the other object using other.edition.
-
College Board’s solution uses the getEdition() method to access the edition of the otherTextbook object, which is a more encapsulated approach. It’s generally a good practice to use getter methods to access private instance variables of another object, even if it’s of the same class.
Final Thoughts
When solving FRQs, it’s essential to read the problem statement carefully and understand the requirements. It’s okay to make mistakes initially, but the key is to review the solution, identify the errors, and correct them. Use ChatGPT, Bard, and videos on Youtube/CollegeBoard that can walk you though the errors. Originally I got a 6/9 on this FRQ, but after revising my mistakes, I completely understood the FRQ. This exercise not only helps in getting the correct solution but also reinforces the understanding of the concepts because if I ever faced another FRQ like this on a practice test or the actual AP exam, I would be comfortable answering it!