TD1 — VSCodium, Maven & First Java Classes
S7 Inf A3 — Java for Graphical and Mobile Programming
Stéphane Derrode — Centrale Lyon
Part 1 — Java Fundamentals
Duration: 2h · Pair or individual work
Objectives
By the end of this session you will be able to:
- Create and run a Maven project in VSCodium
- Write Java classes with private fields, constructors, getters and setters
- Instantiate objects, call methods, and use
toString() - Understand the difference between
==and.equals() - Work with arrays of objects
Part 0 — Environment Setup
This part should already be done before the session.
Follow the VSCodium & Maven Setup Tutorial available on the course website. It walks you through installing JDK 17, Maven, VSCodium, and the Java Extension Pack step by step.
If you have any problem with installation, come 10 minutes early and we will sort it out.
Quick check — open a terminal inside VSCodium and verify:
Part 1 — Create the Maven Project (10 min)
1.1 Create the project
In VSCodium, press Ctrl+Shift+P → type Maven: Create Maven Project → select:
- Archetype:
maven-archetype-quickstart, version1.5 - Group Id:
com.s7infa3 - Artifact Id:
td1
Then File ▸ Open Folder… and select the td1/ folder that was just created.
1.2 Configure Java 17
Replace the content of pom.xml with:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.s7infa3</groupId>
<artifactId>td1</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Save (Ctrl+S). Then open src/main/java/com/s7infa3/App.java, click ▶ Run above main() — you should see Hello World!.
Part 2 — Class Car (45 min)
This Car class is the running example for the whole of Part 1 — it grows in TD2 (collections, file I/O) and TD3 (inheritance).
2.1 UML specification
┌────────────────────────────────────────────┐
│ Car │
├────────────────────────────────────────────┤
│ - model : String │
│ - power : int │
│ - started : boolean │
│ - speed : double │
├────────────────────────────────────────────┤
│ + Car(String model, int power) │
│ + Car(String model) │
│ + getModel() : String │
│ + getPower() : int │
│ + getSpeed() : double │
│ + isStarted() : boolean │
│ + maxSpeed() : int │
│ + start() : void │
│ + stop() : void │
│ + accelerate(double delta) : void │
│ + brake(double delta) : void │
│ + equals(Object obj) : boolean │
│ + hashCode() : int │
│ + toString() : String │
└────────────────────────────────────────────┘
2.2 Behaviour rules
| Method | Behaviour |
|---|---|
Car(String model, int power) |
Stores model. If power > 0, power = power; otherwise power = 70. Always: started = false, speed = 0.0 |
Car(String model) |
Delegate to Car(model, 70) using this(model, 70) |
maxSpeed() |
Returns 80 + power (top speed grows with engine power) |
start() |
Sets started = true |
stop() |
Sets started = false and speed = 0.0 |
accelerate(double delta) |
Only if started and delta > 0: speed = min(speed + delta, maxSpeed()) |
brake(double delta) |
Only if delta > 0: speed = max(0.0, speed - delta) |
equals(Object obj) |
Two Car are equal if they have the same model and same power |
toString() |
Returns "Car[Clio, 90hp, on, 60 km/h]" |
2.3 Skeleton to complete
Create src/main/java/com/s7infa3/Car.java:
package com.s7infa3;
import java.util.Objects;
public class Car {
// TODO: declare the 4 private fields (model is final)
public Car(String model, int power) {
// TODO
}
public Car(String model) {
this(model, 70); // delegates to Car(String, int)
}
public String getModel() { /* TODO */ return ""; }
public int getPower() { /* TODO */ return 0; }
public double getSpeed() { /* TODO */ return 0; }
public boolean isStarted() { /* TODO */ return false; }
public int maxSpeed() { /* TODO: 80 + power */ return 0; }
public void start() { /* TODO */ }
public void stop() { /* TODO */ }
public void accelerate(double delta) {
// TODO: only if started && delta > 0, capped at maxSpeed()
}
public void brake(double delta) {
// TODO: never below 0
}
@Override
public boolean equals(Object obj) {
// TODO: true if obj is a Car with same model and power
return false;
}
@Override
public int hashCode() {
return Objects.hash(model, power);
}
@Override
public String toString() {
// TODO: "Car[Clio, 90hp, on, 60 km/h]"
return "";
}
}
2.4 Test in App.java
Replace App.java with the following and verify every printed value:
package com.s7infa3;
public class App {
public static void main(String[] args) {
// Basic usage
Car clio = new Car("Clio", 90);
clio.start();
clio.accelerate(50);
clio.accelerate(30);
System.out.println(clio);
// Car[Clio, 90hp, on, 80 km/h]
// brake() never goes below 0
clio.brake(20);
System.out.println(clio);
// Car[Clio, 90hp, on, 60 km/h]
// top speed is capped at maxSpeed() = 80 + 90 = 170
clio.accelerate(500);
System.out.println(clio.getSpeed()); // 170.0
// accelerate() has no effect if not started
Car polo = new Car("Polo", 110);
polo.accelerate(50);
System.out.println(polo.getSpeed()); // 0.0
// stop() resets the speed
clio.stop();
System.out.println(clio);
// Car[Clio, 90hp, off, 0 km/h]
// Invalid power → defaults to 70
Car mystery = new Car("Mystery", -10);
System.out.println(mystery.getPower()); // 70
// One-argument constructor (delegates with this(...))
Car twingo = new Car("Twingo");
System.out.println(twingo.getPower()); // 70
// == vs equals()
Car clio2 = new Car("Clio", 90);
System.out.println(clio == clio2); // false (different objects)
System.out.println(clio.equals(clio2)); // true (same model + power)
}
}
Part 3 — Array of Objects: class Garage (25 min)
A Garage manages a fixed-size fleet of Car objects using a plain array (not ArrayList — that is CM2).
3.1 Specification
Create src/main/java/com/s7infa3/Garage.java:
| Member | Description |
|---|---|
Garage(int capacity) |
Creates an array of capacity slots (all null initially) |
add(Car c) |
Adds c to the next free slot; silently ignores if full |
size() |
Returns the number of cars currently stored |
getAt(int i) |
Returns the car at index i; throws IllegalArgumentException if out of range |
startAll() |
Calls start() on every stored car |
toString() |
Returns one car per line |
3.2 Skeleton
package com.s7infa3;
public class Garage {
private Car[] cars;
private int count;
public Garage(int capacity) {
// TODO
}
public void add(Car c) {
// TODO: add only if count < cars.length
}
public int size() { /* TODO */ return 0; }
public Car getAt(int i) {
// TODO: throw IllegalArgumentException if i < 0 or i >= count
return null;
}
public void startAll() {
// TODO: loop over the count stored cars
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
// TODO: append each car + newline
return sb.toString();
}
}
3.3 Test
Add to the end of main():
System.out.println("\n--- Garage ---");
Garage garage = new Garage(5);
garage.add(new Car("Clio", 90));
garage.add(new Car("Polo", 110));
garage.add(new Car("Ferrari", 280));
System.out.println("Size: " + garage.size()); // 3
garage.startAll();
System.out.println(garage.getAt(0));
// Car[Clio, 90hp, on, 0 km/h]
System.out.println(garage);
try {
garage.getAt(10);
} catch (IllegalArgumentException e) {
System.out.println("Caught: " + e.getMessage());
}
Part 4 — Exploration (remaining time)
4.1 Add a private static int carsCreated = 0 counter to Car, incremented in every constructor. Add public static int getCarsCreated(). Test that after creating 5 cars the counter returns 5.
4.2 Add a cruiseAt(double v) method: set the speed directly to v, but only if the car is started and 0 <= v <= maxSpeed(). If v < 0, throw IllegalArgumentException.
4.3 You already override both equals() and hashCode(). Why is it important to override them together? (Hint: think of HashMap<Car, String> — what happens if two equal cars return different hash codes?)
Deliverable
No formal submission for TD1. Verify all outputs match the expected values before leaving.
Keep this project — it will be extended in TD2.
Common Errors
| Error | Cause | Fix |
|---|---|---|
cannot find symbol |
Typo or missing import | Check spelling; Ctrl+. in VSCodium to auto-fix |
incompatible types |
Wrong type assigned | Check declared type matches the value |
NullPointerException |
Array slot is null |
Make sure count tracks filled slots correctly |
ArrayIndexOutOfBoundsException |
Index out of range | Guard with i >= 0 && i < count in getAt() |
accelerate() has no visible effect |
Car not started | Call start() before accelerate() |
| Speed never exceeds a ceiling | That is maxSpeed() doing its job |
Expected — accelerate() is capped at 80 + power |