Trio: 2014 FRQ 4
A step-by-step solution to the 2014 AP CSA FRQ 4 (Trio), covering implementing an interface with specific parameter types and computing a price rule based on the two highest values in Java.
A lunch-counter menu where bundling three items together makes the cheapest one free is the idea behind this AP Computer Science A free-response question — and the whole task is writing one class from scratch that plugs into an existing interface built around it.
What This FRQ Tests
- AP CSA units: Unit 9 (Inheritance, specifically interfaces) and Unit 5 (Writing Classes)
- Core skill: implementing an interface (
implements MenuItem) by supplying concrete versions of every method it declares - Secondary skill: choosing constructor parameter types deliberately, so that passing the wrong kind of object fails to compile instead of failing silently at run time
- Official category: "Classes" (specifically, implementing an interface), which is normally FRQ 2's position — 2014's actual printed order deviates from the now-standard sequence: FRQ 1 (Scramble, Methods and Control Structures), FRQ 2 (a GridWorld case-study question, excluded from this set), FRQ 3 (SeatingChart, 2D Array), and FRQ 4 (Trio, Classes). The fixed 1‑Methods/Control Structures, 2‑Classes, 3‑Array/ArrayList, 4‑2D Array ordering used on modern exams wasn't standardized until the 2019–2020 Course and Exam Description redesign.
The Setup
- The
MenuIteminterface (given, not modified) declares two methods every menu item must provide:String getName()double getPrice()
- Four classes all implement
MenuItem:Sandwich,Salad,Drink, and the one you're writing,Trio. (Sandwich,Salad, andDrink's internals aren't shown — only that each has a name and a price, reachable through the interface's two methods.) - A
Triobundles exactly oneSandwich, oneSalad, and oneDrink:- Its name is the three items' names, in that order, joined by
"/", followed by a space and the word"Trio"— e.g."Cheeseburger/Spinach Salad/Orange Soda Trio". - Its price is the sum of the two highest-priced items in the bundle — the one lowest-priced item is free.
- Its name is the three items' names, in that order, joined by
- The constructor must be written so that
new Trio(sandwich, salad, drink)compiles, but calls with the arguments in the wrong order, or with a repeated type (like two salads), fail to compile.
Building the Trio Class
Step-by-Step Approach
- Declare
Trioaspublic class Trio implements MenuItem— this is what makes it a validMenuItemand requires it to providegetName()andgetPrice(). - Give the constructor three parameters typed specifically as
Sandwich,Salad, andDrink— not a genericMenuItemfor all three. Using the specific types is exactly what makesnew Trio(salad, sandwich, drink)andnew Trio(sandwich, salad, salad)fail to compile: Java checks argument types against parameter types, and aSaladsimply isn't aSandwichor aDrink. - Inside the constructor, build the combined name string right away and store it.
- Also inside the constructor, work out which of the three prices is lowest, then compute and store the total as "sum of all three, minus the lowest one" — which is mathematically the same as "sum of the two highest."
- Store both the computed name and price as fields, and have
getName()/getPrice()simply return them.
The Code
public class Trio implements MenuItem
{
private String name;
private double price;
public Trio(Sandwich sandwich, Salad salad, Drink drink)
{
name = sandwich.getName() + "/" + salad.getName() + "/" + drink.getName() + " Trio";
double sandwichPrice = sandwich.getPrice();
double saladPrice = salad.getPrice();
double drinkPrice = drink.getPrice();
double lowest = sandwichPrice;
if (saladPrice < lowest)
{
lowest = saladPrice;
}
if (drinkPrice < lowest)
{
lowest = drinkPrice;
}
price = sandwichPrice + saladPrice + drinkPrice - lowest;
}
public String getName()
{
return name;
}
public double getPrice()
{
return price;
}
}
Why Each Piece Matters
Sandwich sandwich, Salad salad, Drink drinkas the parameter types — this single choice is what produces the two required compile-time errors.new Trio(salad, sandwich, drink)tries to pass aSaladwhere aSandwichis expected, andnew Trio(sandwich, salad, salad)tries to pass aSaladwhere aDrinkis expected — both are type mismatches Java catches before the program ever runs.- "Sum of all three minus the lowest" instead of "sum of the two highest" — these are the same value, but computing a single minimum is simpler than identifying and adding two different values out of three, especially without a sorting method on the Quick Reference sheet to lean on.
- Two separate
ifchecks, notif/else if— the lowest price could be the salad's, or it could turn out to be the drink's after already being updated to the salad's price. Each check needs to run independently against whateverlowestcurrently holds, which is exactly what two back-to-backifstatements (not a mutually-exclusiveif/else ifchain) accomplish. - Computing
nameandpriceonce, in the constructor — since none ofsandwich,salad, ordrinkcan change after aTriois built, computing both values a single time and storing them is simpler than recomputing them from scratch on every call togetName()/getPrice().
Tracing the Example
Using the question's own sample items — sandwich = "Cheeseburger" (2.75), salad = "Spinach Salad" (1.25), drink = "Orange Soda" (1.25):
name→"Cheeseburger" + "/" + "Spinach Salad" + "/" + "Orange Soda" + " Trio"→"Cheeseburger/Spinach Salad/Orange Soda Trio"loweststarts at2.75(the sandwich price).1.25 < 2.75is true →lowest = 1.25.1.25 < 1.25is false →loweststays1.25.price→2.75 + 1.25 + 1.25 - 1.25=4.00
Both match the question's stated expected result exactly.
A second check with the question's other example — "Club Sandwich" (2.75), "Coleslaw" (1.25), "Cappuccino" (3.50):
name→"Club Sandwich/Coleslaw/Cappuccino Trio"loweststarts at2.75.1.25 < 2.75is true →lowest = 1.25.3.50 < 1.25is false →loweststays1.25.price→2.75 + 1.25 + 3.50 - 1.25=6.25
Both again match the question's stated expected result exactly.
Common Mistakes to Avoid
- Typing the constructor's parameters as
MenuIteminstead ofSandwich/Salad/Drink. This would let every one ofnew Trio(salad, sandwich, drink)andnew Trio(sandwich, salad, salad)compile without error — directly contradicting the problem's explicit requirement that both fail to compile. - Subtracting the wrong value, like the highest price instead of the lowest. The rule is "sum of the two highest," which comes from removing the lowest — not the other way around.
- Using
if/else ifto find the lowest price. Once the first branch of anelse ifchain runs, no later branch can run for that same check — which can miss updatinglowesta second time when the drink turns out to be even cheaper than the salad. - Forgetting the
" Trio"suffix, or getting the separator wrong. The name format is exact: each name joined by"/", then a single space, then the literal word"Trio"— not" - Trio"or"-Trio"or any other punctuation.
Notes: A Method Not on the AP CSA Quick Reference Sheet
Math.min can find the lowest of the three prices in a single nested expression instead of two separate if statements:
public Trio(Sandwich sandwich, Salad salad, Drink drink)
{
name = sandwich.getName() + "/" + salad.getName() + "/" + drink.getName() + " Trio";
double sandwichPrice = sandwich.getPrice();
double saladPrice = salad.getPrice();
double drinkPrice = drink.getPrice();
double lowest = Math.min(sandwichPrice, Math.min(saladPrice, drinkPrice));
price = sandwichPrice + saladPrice + drinkPrice - lowest;
}
Math.min(a, b)returns whichever of the two arguments is smaller. Nesting one call inside another —Math.min(sandwichPrice, Math.min(saladPrice, drinkPrice))— extends it to three values by first finding the smaller of the last two, then comparing that result against the first.- Neither
Math.minnorMath.maxappears on the real exam's Java Quick Reference sheet (onlyabs,pow,sqrt, andrandomare listed for theMathclass) — but that doesn't mean either one is off-limits. AP CSA graders accept any correct Java. The tradeoff is simply that you can't lookMath.min's exact behavior up on the reference sheet during the exam if you're unsure of it; the two-ifversion above doesn't depend on remembering it at all.
Key Takeaways
- Choosing specific parameter types (
Sandwich,Salad,Drink) instead of a shared, more general type (MenuItem) is itself a design decision with real consequences — it's what turns a mismatched argument into a compile-time error instead of a bug that only shows up later. - "Sum minus the smallest" and "sum of the two largest" are the same computation for exactly three values — finding one minimum is simpler than identifying and adding two different values.
- When a class caches a computed value (like
nameorprice) in its constructor instead of recomputing it on every getter call, that's a valid tradeoff as long as nothing the value depends on can change afterward.