Exercise 1 of 4
Your First Class
A class is a blueprint for objects:
class Dog {
String name;
}
You create an object with new:
Dog d = new Dog();
d.name = "Buddy";
Set the car's brand to BMW before it gets printed.
Starter code
void main() {
Car c = new Car();
// Set c.brand to "BMW"
IO.println(c.brand);
}
class Car {
String brand;
}
Background
OOP — Object-Oriented Programming
Java is an object-oriented language. The idea: you model the world as objects with properties (fields) and behavior (methods). A Car has a brand and can drive().
The four pillars of OOP: abstraction, encapsulation, inheritance and polymorphism. You'll get to know them step by step.
Exercise 2 of 4
Constructor
Instead of setting values one by one, you use a constructor — a special method that runs when the object is created:
class Dog {
String name;
Dog(String name) {
this.name = name;
}
}
this.name = the field of the class. name = the parameter.
Complete the constructor of the Car class.
Starter code
void main() {
Car c = new Car("Tesla");
IO.println(c.brand);
}
class Car {
String brand;
Car(String brand) {
// Set this.brand to the parameter brand
}
}
Background
this — the self-reference
this refers to the current object. In the constructor you need this.brand = brand; because the parameter brand has the same name as the field. Without this, Java would think you're assigning the parameter to itself — and the field stays null.
Tip: Lots of Java developers deliberately give parameters the same names as the fields and use this. — that's common style.
Exercise 3 of 4
Methods in a Class
Classes can have their own methods:
class Dog {
String name;
String bark() {
return name + " says Woof!";
}
}
The method can access the fields of the class — no parameters needed.
Complete the method info(): it should return [brand], [hp] hp.
Starter code
void main() {
Car c = new Car("BMW", 150);
IO.println(c.info());
}
class Car {
String brand;
int hp;
Car(String brand, int hp) {
this.brand = brand;
this.hp = hp;
}
String info() {
// Return "[brand], [hp] hp"
return "";
}
}
Background
toString() — the universal method
Every class in Java inherits from Object and has a toString() method. When you call println(object), object.toString() is called automatically.
Without your own toString() you get something like Car@1a2b3c — the class name plus the object's hash code in hex (not a memory address, even though it looks like one). That's why you almost always override toString().
Exercise 4 of 4
Inheritance
A class can inherit from another one — it takes over all its fields and methods:
class Animal { String name; }
class Dog extends Animal { String breed; }
Dog now has name (inherited from Animal) and breed.
In the constructor you call super() to run the constructor of the parent class.
Complete the constructor of ElectricCar: call super(brand) and set range.
Starter code
void main() {
ElectricCar e = new ElectricCar("Tesla", 500);
IO.println(e.brand + ", " + e.range + " km");
}
class Car {
String brand;
Car(String brand) { this.brand = brand; }
}
class ElectricCar extends Car {
int range;
ElectricCar(String brand, int range) {
// Call super(brand)
// Set this.range
}
}
Background
Inheritance and the class hierarchy
In Java a class can inherit from only one class (single inheritance). For "multiple inheritance" there are interfaces — abstract contracts that a class can implement.
For a long time super() had to be the very first statement in a constructor. Since Java 25 you may put a few statements before it (e.g. checking parameters), as long as they don't touch this. The point stays the same: the parent part of the object gets initialized before the child class works with its own fields. Putting super() first is still the usual style.