PF 101 study hub

PF 101 · Day 2 · Track B · ~90–120 min

Ride Start → Private, Fare, Boarded

Same garage. Lock #maxPax and #boarded. Add fare(), alight(), and startAll() — Garage still never asks the type.

Final output

What Day 2 looks like

Fare · Alight · Start all. Habal fill → illegal → alight → sakay again.

Open full screen

Before you start

Track B only

Same repo. No new folder. If Start + Sakay are not working yet, finish Day 1 first.

Full typed walkthrough: ACTIVITY-ride-start-private-fare.md

STEP 1

Private label + capacity

  1. 1

    Edit js/ride.js: add #label and #maxPax.

  2. 2

    Constructor: constructor(label, maxPax). Getter for label. maxPassengers() returns #maxPax.

  3. 3

    Subclasses: super('Habal-habal', 3) — delete hard-coded max overrides.

Ridebeat A
#label;
#maxPax;
constructor(label, maxPax) { … }
maxPassengers() { return this.#maxPax; }

ride.#maxPax = 99 → SyntaxError. Private means outsiders cannot touch it.

STEP 2

Private fare rate + fareTag()

  1. 1

    Extend constructor: constructor(label, maxPax, fareRate) with private #fareRate.

  2. 2

    Parent fare(n) does the math. Subclasses only override fareTag() (funny label).

  3. 3

    Rates: Jeep ₱13 · Trike ₱20 · Habal ₱25 via super(…, rate).

Motorcyclebeat B
constructor() {
  super('Habal-habal', 3, 25);
}
fareTag() { return 'Special trip'; }

Same fare() path. Different tags and rates. Polymorphism + encapsulation.

STEP 3

Garage.fareSelected + Fare button

  1. 1

    Add fareSelected(count) — only calls this.#selected.fare(count).

  2. 2

    HTML: Fare button. CSS: .fare-btn. Wire in main.js.

  3. 3

    No instanceof.

GaragefareSelected
fareSelected(count) {
  return this.#selected.fare(count);
}

Habal Fare(2) → ₱50. Jeep Fare(2) → ₱26. Same button.

STEP 4

Private #boarded + seatsLeft

  1. 1

    Add #boarded = 0, boarded(), seatsLeft().

  2. 2

    Rewrite sakay(n) to check seatsLeft(), then #boarded += n.

  3. 3

    Add alight(n) — cannot alight more than aboard.

Ride.sakaybeat C
if (n > this.seatsLeft()) {
  return 'Pffft… illegal recruitment. '
    + this.seatsLeft() + ' seat(s) left…';
}
this.#boarded += n;
return this.boardOk(n) + ' · aboard ' + this.#boarded + '/' + this.#maxPax;

Habal sakay(2) → sakay(2) illegal (1 left) → alight(1) → sakay(1) ok.

STEP 5

Garage alightSelected + startAll

  1. 1

    Add alightSelected(count) and statusSelected().

  2. 2

    Add startAll() — map every ride's start() into one string.

  3. 3

    Still zero instanceof. This is the polymorphism loop.

Garage.startAllbeat D
startAll() {
  return this.#rides
    .map((ride) => ride.label + ': ' + ride.start())
    .join(' · ');
}

startAll() shouts Jeep + Habal + … in one line without asking types.

STEP 6

Wire Alight + Start all + list aboard

  1. 1

    HTML: Alight button + Start all button. Style both.

  2. 2

    List rows show aboard 2/3. Refresh list after sakay/alight.

  3. 3

    Hint uses garage.statusSelected().

main.jswire
alightBtn.addEventListener('click', () => {
  const line = garage.alightSelected(paxInput.value);
  showLine(line, garage.selected().kind() + '.alight(…)');
  hint.textContent = garage.statusSelected();
  renderList();
});

startAllBtn.addEventListener('click', () => {
  showLine(garage.startAll(), 'garage.startAll()');
});

Compare with the final output demo when stuck.

Done checklist

Submit

Same Ride Start repo — new commits. Paper answers for the shared drill.

DeliverableWhat to turn in
RepoSame GitHub URL — commits for private, fare, boarded, startAll
DemoFare(2) Habal≠Jeep · fill habal then illegal sakay · alight · Start all
DefenseWhy #boarded is private; why startAll needs no instanceof

Still building Day 1? Open Ride Start core