Day 2 Notes: Car Class – Variables, Constructors, and Basic Methods
Day 2 notes: Expanding the Car class with new fields, constructors, and basic methods
Recap from Day 1
- We built a Car class (a blueprint) with properties (fields/instance variables) such as max speed, min speed, and weight.
- We had methods to display or change those properties.
- Our main function acted like a body shop: it creates car instances and uses methods to modify them.
New instance variables added
- max fuel: a double representing the maximum fuel capacity in gallons
- Declaration and initialization: max fuel is set to 16 gallons
- Purpose: the tank’s capacity for fueling calculations
- ext{maxFuel} = 16 ext{ gallons}
- current fuel: a double representing the current gallons in the tank, initialized to 8 gallons
- Declaration with initialization: currentFuel = 8
- Rationale for using double: fuel can be a fractional quantity (e.g., 8.5 gallons)
- mpg: a double for miles per gallon, representing fuel efficiency (average ~ 26.4 mpg)
- Declaration with initialization: mpg = 26.4
- Rationale: degree of precision needed for mileage calculations
- number of people in the car: an int representing current occupants
- Declaration with initialization: numberOfPeopleInCar = 1
- Rationale: you can’t have fractional people; an int is appropriate
Understanding instance variables
- All the fields above are instance variables (belong to each Car object)
- They have default values but can vary per instance (e.g., a family car vs a sports car)
- Example variations:
- A different car might have a larger fuel tank (e.g., 24 gallons) or a different mpg value
Constructors: creating a car with custom initial values
- What a constructor does: builds an instance from the class blueprint and can set initial values for fields
- Basic idea: the constructor name must match the class name and is used to initialize new objects
- Parameters vs. arguments
- A parameter is a variable in the constructor declaration (its type and name)
- An argument is the actual value you pass when you call new Car(…)
- Example: A constructor signature might look like public Car(int minSpeed, int maxSpeed, double weight, boolean isOn)
- When you call new Car(10, 500, 5000.5, true), 10, 500, 5000.5, and true are the arguments; minSpeed, maxSpeed, weight, isOn are the corresponding parameters
- Mapping arguments to parameters
- The order matters: the first argument goes to the first parameter, the second to the second, etc.
- Example: minSpeed = 10, maxSpeed = 500, weight = 5000.5, isOn = true
- Implementing the constructor to set fields
- Inside the constructor, assign the values to the fields, e.g.:
- minSpeed = customMinSpeed; // if you name the parameter customMinSpeed
- maxSpeed = customMaxSpeed;
- weight = customWeight;
- isOn = customIsOn;
- Important ordering note: ensure the assignment uses the parameter values (not the other way around) so the fields actually get updated
- Practical example (using descriptive names):
- Constructor signature: public Car(int minSpeed, int maxSpeed, double weight, boolean isOn)
- Inside:
- this.minSpeed = minSpeed;
- this.maxSpeed = maxSpeed;
- this.weight = weight;
- this.isOn = isOn;
- Realistic usage with a birthday present car
- Birthday present car example (custom values):
- Arguments: minSpeed = 10, maxSpeed = 500, weight = 5000.5, isOn = true
- Code: birthdayPresent = new Car(10, 500, 5000.5, true);
- This shows how a constructor can give a car a unique starting state different from defaults
- Another example: Christmas present car
- Sports-car-like settings: maxSpeed = 550, weight = 2000, isOn = false (still uses constructor to set these)
- Code: christmasPresent = new Car(0, 550, 2000, false);
- Note: minSpeed is given a value here (0) to keep a valid argument list; you could choose a different sensible default
- Why use constructors at all?
- They allow you to create custom objects with specific starting states, ensuring each instance can be tailored
- You can still rely on default values for convenience if you don’t need customization
Using the new constructor + objects in code
- Create two cars and show their independence
- birthdayPresent.printVariables();
- christmasPresent.printVariables();
- Demonstrate independence: changing one car’s properties does not affect the other
- Main method as a testbed
- Call methods on specific objects, e.g., birthdayPresent.printVariables(), birthdayPresent.getIn(), etc.
- Practical demonstration outcome:
- Birthday present car attributes after customization show maxSpeed = 500, weight = 5000.5, isOn = true, minSpeed = 10 (from constructor)
- Christmas present car attributes show their own values (e.g., maxSpeed = 550, weight = 2000, isOn = false)
Instance methods to manipulate state and perform calculations
- getIn(): simulate a person getting into the car
- Increment numberOfPeopleInCar by 1
- Using the shorthand: numberOfPeopleInCar++ is equivalent to numberOfPeopleInCar = numberOfPeopleInCar + 1
- getOut(): simulate a person leaving the car
- Decrement numberOfPeopleInCar by 1
- Using shorthand: numberOfPeopleInCar-- is equivalent to numberOfPeopleInCar = numberOfPeopleInCar - 1
- howManyMilesTillOutOfGas(): returns how many miles you can still drive with current fuel
- Formula: ext{milesLeft} = ext{currentFuel} imes ext{mpg}
- Return type: double
- maxMilesPerFillUp(): returns the maximum miles you can drive on a full tank
- Formula: ext{maxMiles} = ext{maxFuel} imes ext{mpg}
- Return type: double
- Rationale for these methods
- Encapsulation and reuse: calculations are centralized in methods so you don’t duplicate logic in main
- Maintainability: if you change how miles are calculated, you update a single method
- Readability: methods like getIn(), getOut(), howManyMilesTillOutOfGas() read like natural language and describe behavior clearly
Simple numeric examples from the video
- Given: ext{currentFuel} = 8, ext{ maxFuel} = 16, ext{ mpg} = 26.4
- Miles left with current fuel: 8 imes 26.4 = 211.2 miles
- Miles per full tank: 16 imes 26.4 = 422.4 miles
- These values demonstrate why double precision matters for fuel calculations
Why the method-based approach matters (software engineering principles)
- Separation of concerns: distinct methods for printing, updating state, and computing derived values
- Easier debugging: locate issues in a single method rather than hunting through a long main function
- Reusability: one method can be called from multiple places without rewriting logic
- Modularity and future-proofing: you can evolve the class (e.g., add more fields or more complex fuel math) without breaking existing code
- The idea of “procrastination” in coding humor: build the core logic first in methods that can be reused later, then wire everything up in main
Practical coding practices illustrated
- Use comments to disable or annotate code (commenting out the Christmas car loop) without deleting it
- Use descriptive names for parameters and methods to improve readability (minSpeed, maxSpeed, customWeight, customIsOn, printVariables, getIn, getOut)
- Keep default values separate from customization so you can always fall back to sane defaults if a constructor isn’t provided with all parameters
- Note on syntax and ordering in constructors: ensure parameter assignment uses the correct parameter value to avoid logical errors
Real-world relevance and connections
- Object-oriented programming concepts shown here (classes, instance variables, constructors, instance methods) mirror real-world design: template blueprints (classes) produce multiple products (instances) with their own states
- The approach aligns with software engineering best practices: modularization, encapsulation, and single-responsibility for methods
- The analogy of building cars in a body shop helps connect programming constructs to tangible tasks
Quick recap of key terms
- Instance variable: a field whose value is unique to each object (e.g., minSpeed, maxSpeed, weight, currentFuel, numPeopleInCar)
- Constructor: a special method used to create and initialize an instance of a class
- Parameter vs Argument: a parameter is a named variable in a method signature; an argument is the actual value passed when the method is called
- Method (instance method): a function defined in a class that operates on an instance’s data
- Miles calculations: use ext{milesLeft} = ext{currentFuel} imes ext{mpg} and ext{maxMiles} = ext{maxFuel} imes ext{mpg}
Final takeaways
- You learned how to declare and initialize new instance variables, create a constructor that can customize per-object state, and write several instance methods to manipulate state and compute useful values
- You saw how to test objects independently and the importance of keeping code modular for future maintenance
- You observed how math operators (+, -, *, /) and shorthand (++/--) are used inside methods to update state
Optional practice prompts
- Implement another constructor overload that defaults some fields when not all parameters are provided
- Add a method to refuel the car (e.g., void refuel(double gallons) that increases currentFuel up to maxFuel)
- Experiment with creating multiple car instances with different starting configurations and verify their independence by printing their states after online operations
Reference to the Hacker Ink challenge and upcoming sessions
- The challenge description is linked in the video description; you can revisit it for hands-on practice
- Expect another session tomorrow to continue building on these concepts