Computer Science A
2022 FRQ 2
- FRQ Question
- Solution code below (college board!)
- 0 – Be Aware of Common FRQ Penalties
- 1 – Correct Use of Inheritance (
extends Book) - 2 – Proper Placement of Instance Variables
- 3 – Constructor Uses
superto Initialize Inherited Data - 4 – Accessor Method for Edition (
getEdition) - 5 – Overriding
getBookInfoCorrectly - 6 – Correct Logic in
canSubstituteFor - 7 – Matching the Sample Execution Table
- 8 – No Extraneous or Penalized Code
- Scoring Guidelines Part A
- Scoring Criteria and Decision Rules
- 1-Point Penalty
- No Penalty
FRQ Question
The Book class is used to store information about a book. A partial Book class definition is shown.
public class Book { /** The title of the book */ private String title;
/** The price of the book */
private double price;
/** Creates a new Book with given title and price */
public Book(String bookTitle, double bookPrice)
{ /* implementation not shown */ }
/** Returns the title of the book */
public String getTitle()
{ return title; }
/** Returns a string containing the title and price of the Book */
public String getBookInfo()
{
return title + "-" + price;
}
// There may be instance variables, constructors, and methods that are not shown. }
You will write a class Textbook, which is a subclass of Book.
A Textbook has an edition number, which is a positive integer used to identify different versions of the book. The getBookInfo method, when called on a Textbook, returns a string that also includes the edition information, as shown in the example.
Information about the book title and price must be maintained in the Book class. Information about the edition must be maintained in the Textbook class.
The Textbook class contains an additional method, canSubstituteFor, which returns true if a Textbook is a valid substitute for another Textbook and returns false otherwise. The current Textbook is a valid substitute for the Textbook referenced by the parameter of the canSubstituteFor method if the two Textbook objects have the same title and if the edition of the current Textbook is greater than or equal to the edition of the parameter.
The following table contains a sample code execution sequence and the corresponding results. The code execution sequence appears in a class other than Book or Textbook.
| Statement | Value Returned (blank if no value) |
Class Specification |
|---|---|---|
Textbook bio2015 = new Textbook("Biology", 49.75, 2); |
bio2015 is a Textbook with a title of "Biology", a price of 49.75, and an edition of 2. |
|
Textbook bio2019 = new Textbook("Biology", 39.75, 3); |
bio2019 is a Textbook with a title of "Biology", a price of 39.75, and an edition of 3. |
|
bio2019.getEdition(); |
3 |
The edition is returned. |
bio2019.getBookInfo(); |
"Biology-39.75-3" |
The formatted string containing the title, price, and edition of bio2019 is returned. |
bio2019.canSubstituteFor(bio2015); |
true |
bio2019 is a valid substitute for bio2015, since their titles are the same and the edition of bio2019 is greater than or equal to the edition of bio2015. |
bio2015.canSubstituteFor(bio2019); |
false |
bio2015 is not a valid substitute for bio2019, since the edition of bio2015 is less than the edition of bio2019. |
Textbook math = new Textbook("Calculus", 45.25, 1); |
math is a Textbook with a title of "Calculus", a price of 45.25, and an edition of 1. |
|
bio2015.canSubstituteFor(math); |
false |
bio2015 is not a valid substitute for math, since the title of bio2015 is not the same as the title of math. |
Problem: Write the complete Textbook class. Your implementation must meet all specifications and conform to the examples shown in the preceding table
Down below is an interactive coderunner. Feel free to use it in order to get a better understanding of the question and answer
Code Runner Challenge
Solutions for Extending the Book Class
View IPYNB Source
// CODE_RUNNER: Solutions for Extending the Book Class
class Book {
private String title;
private double price;
public Book(String t, double p) {
title = t;
price = p;
}
public String getTitle() {
return title;
}
public String getBookInfo() {
return title + "," + price;
}
}
public class Main extends Book {
private int edition;
public Main(String tbTitle, double tbPrice, int tbEdition) {
super(tbTitle, tbPrice);
edition = tbEdition;
}
public int getEdition() {
return edition;
}
public boolean canSubstituteFor(Main other) {
return other.getTitle().equals(getTitle()) &&
edition >= other.getEdition();
}
public String getBookInfo() {
return super.getBookInfo() + "-" + edition;
}
// REQUIRED for code runner
public static void main(String[] args) {
Main t1 = new Main("AP Biology", 59.99, 3);
Main t2 = new Main("AP Biology", 49.99, 2);
System.out.println(t1.getBookInfo());
System.out.println(t1.canSubstituteFor(t2));
}
}
// Call main
Main.main(null);
Solution code below (college board!)
public class Textbook extends Book
{
private int edition;
public Textbook(String tbTitle, double tbPrice, int tbEdition)
{
super(tbTitle, tbPrice);
edition = tbEdition;
}
public int getEdition()
{
return edition;
}
public boolean canSubstituteFor(Textbook other)
{
return other.getTitle().equals(getTitle()) &&
edition >= other.getEdition();
}
public String getBookInfo()
{
return super.getBookInfo() + "-" + edition;
}
}
AP CSA FRQ: Textbook Class — Explanation and Guidance
This document explains why the provided Textbook solution earns full credit and highlights common pitfalls students should avoid. The explanations are aligned with AP CSA Free Response Question (FRQ) grading expectations.
0 – Be Aware of Common FRQ Penalties
These mistakes can cause point deductions on any FRQ and should always be avoided.
- Duplicating instance variables that already exist in a superclass
- Accessing private data directly instead of using methods
- Using
==instead of.equals()to compare Strings - Adding unnecessary or extraneous code that affects program behavior
- Failing to follow method specifications exactly
1 – Correct Use of Inheritance (extends Book)
Explanation
The FRQ requires Textbook to be a subclass of Book. This is correctly implemented using inheritance:
public class Textbook extends Book
This allows Textbook to reuse the title, price, and methods such as getTitle() and getBookInfo() without redefining them. This ensures that title and price information remain in the Book class, as required by the prompt.
2 – Proper Placement of Instance Variables
Explanation
The prompt states that a textbook has an edition number, which should be stored in the Textbook class:
private int edition;
The edition variable is not placed in Book because not all books have editions. This follows proper object-oriented design and avoids duplication of data.
3 – Constructor Uses super to Initialize Inherited Data
Explanation
The constructor must initialize title and price using the Book class and edition using the Textbook class:
public Textbook(String tbTitle, double tbPrice, int tbEdition) {
super(tbTitle, tbPrice);
edition = tbEdition;
}
Calling super(tbTitle, tbPrice) ensures that title and price are stored in the Book object. Direct access to title or price would be incorrect because they are private in Book.
4 – Accessor Method for Edition (getEdition)
Explanation
The sample execution calls getEdition(), so an accessor method must be provided:
public int getEdition() {
return edition;
}
This method returns the edition number and allows other classes to access it without violating encapsulation.
5 – Overriding getBookInfo Correctly
Explanation
The FRQ specifies that getBookInfo() in Textbook should include the edition in the returned string:
public String getBookInfo() {
return super.getBookInfo() + "-" + edition;
}
Using super.getBookInfo() preserves the original formatting from Book and avoids rewriting code. Appending the edition produces the exact format shown in the sample output.
6 – Correct Logic in canSubstituteFor
Explanation
A textbook can substitute for another if:
- The titles are the same
- The edition of the current textbook is greater than or equal to the other
public boolean canSubstituteFor(Textbook other) { return other.getTitle().equals(getTitle()) && edition >= other.getEdition(); }
The .equals() method is used to compare Strings correctly, and the logical AND ensures both conditions must be true.
7 – Matching the Sample Execution Table
Explanation
This implementation produces all expected results:
getEdition()returns the correct edition numbergetBookInfo()returns a correctly formatted stringcanSubstituteFor()returns true or false exactly as shown in the table
This confirms the logic matches the problem specification.
8 – No Extraneous or Penalized Code
Explanation
The solution:
- Does not redefine title or price
- Does not include unnecessary output statements
- Does not modify persistent data unintentionally
- Includes only required methods and instance variables
This prevents common AP CSA scoring deductions.
Scoring Guidelines Part A
AP CSA FRQ Scoring Guidelines - Textbook Class
Scoring Criteria and Decision Rules
| # | Scoring Criteria | Decision Rules | Points |
|---|---|---|---|
| 1 | Declares class header (must not be private):class Textbook extends Book |
1 point | |
| 2 | Declares constructor header:public Textbook(String ___, double ___, int ___) |
1 point | |
| 3 | Constructor calls super as the first line with the appropriate parameters |
1 point | |
| 4 | Declares appropriate private instance variable and uses appropriate parameter to initialize it |
Responses will not earn the point if they • omit the keyword private• declare the variable outside the class, or in the class within a method or constructor • redeclare and use the instance variables of the superclass |
1 point |
| 5 | Declares at least one required method and all declared headers are correct:public boolean canSubstituteFor(Textbook ___)public int getEdition()public String getBookInfo() |
Responses will not earn the point if they • exclude public |
1 point |
| 6 | getEdition returns value of instance variable |
Responses will not earn the point if they • fail to create an instance variable for the edition |
1 point |
| 7 | canSubstituteFor determines whether true or false should be returned based on comparison of book titles and editions (algorithm) |
Responses can still earn the point even if they • fail to return (return is not assessed for this method) • access the edition without calling getEdition• redeclare and use the title variable of the superclass instead of calling getTitleResponses will not earn the point if they • fail to use equals• call getTitle incorrectly in either location |
1 point |
| 8 | getBookInfo calls super.getBookInfo |
Responses can still earn the point even if they • redeclare and use the instance variables of the superclass Responses will not earn the point if they • include parameters |
1 point |
| 9 | Constructs information string | Responses can still earn the point even if they • call super.getBookInfo incorrectly• fail to call super.getBookInfo and access title and price directly• fail to return (return is not assessed for this method) Responses will not earn the point if they • omit the literal hyphen(-) in the constructed string • omit the edition in the constructed string • concatenate strings incorrectly |
1 point |
Total: 9 points
Applying the Scoring Criteria
Apply the question scoring criteria first, which always takes precedence. Penalty points can only be deducted in a part of the question that has earned credit via the question rubric. No part of a question (a, b, c) may have a negative point total. A given penalty can be assessed only once for a question, even if it occurs multiple times or in multiple parts of that question. A maximum of 3 penalty points may be assessed per question.
1-Point Penalty
- v) Array/collection access confusion ([] get)
- w) Extraneous code that causes side-effect (e.g., printing to output, incorrect precondition check)
- x) Local variables used but none declared
- y) Destruction of persistent data (e.g., changing value referenced by parameter)
- z) Void method or constructor that returns a value
No Penalty
- Extraneous code with no side-effect (e.g., valid precondition check, no-op)
- Spelling/case discrepancies where there is no ambiguity*
- Local variable not declared provided other variables are declared in some part
privateorpublicqualifier on a local variable- Missing
publicqualifier on class or constructor header - Keyword used as an identifier
- Common mathematical symbols used for operators (× • ÷ ≤ ≥ <> ≠)
[]vs.()vs.<>=instead of==and vice versalength/sizeconfusion for array,String,List, orArrayList; with or without()- Extraneous
[]when referencing entire array [i,j]instead of[i][j]- Extraneous size in array declaration, e.g.,
int[size] nums = new int[size]; - Missing
;where structure clearly conveys intent - Missing
{ }where indentation clearly conveys intent - Missing
()on parameter-less method or constructor invocations - Missing
()aroundiforwhileco