What I Learned
Core competencies and skills developed throughout this module
Classes, Objects & Constructors
Understood a class as a blueprint and objects as concrete instances, each with its own state, created and initialised through constructors.
- Creating objects with new and calling their methods
- Overloading constructors with different parameter lists
- Using this to distinguish attributes from parameters
- Deciding what an object stores and what it calculates
Encapsulation & static Members
Protected the internal state of objects and learned which members belong to the class itself instead of to an instance.
- Making attributes private and exposing getters and setters
- Validating values in setters and leaving out setters on purpose
- Using static for shared helpers and static final for constants
- Following naming conventions such as isFilled() for booleans
Relationships Between Classes
Modelled how objects work together and documented the structure in UML class diagrams.
- Association: one object knows another
- Aggregation and composition: one object contains others
- Drawing UML class diagrams with multiplicities
- Guarding against NullPointerException for optional references
Collections: From Array to ArrayList
Replaced fixed-size arrays with dynamic collections and used generics for type safety.
- Comparing arrays with a fixed length to a growing ArrayList
- Adding, removing and iterating with add(), remove() and for-each
- Using generics like ArrayList<Runner> for type safety
- Understanding wrapper types like Integer for primitives
Inheritance, Abstract Classes & Polymorphism
Reused and specialised behaviour through class hierarchies, letting the same method call do different things depending on the object.
- Extending classes with extends and calling super()
- Declaring abstract classes and abstract methods
- Overriding methods and using @Override
- Using polymorphism through a common supertype or interface
Object Methods: toString, equals & compareTo
Overrode the methods every class inherits from Object and implemented Comparable to make custom objects sortable.
- Overriding toString() for a readable description
- Comparing contents with equals() instead of references with ==
- Implementing Comparable and compareTo() for a natural order
- Sorting lists with Collections.sort()
Code Examples
Practical examples from the module
/** * Abstract base class: every shape has a name and an area, * but only the subclasses know how to calculate it. */ public abstract class Shape { private final String name; protected Shape(String name) { this.name = name; } public String getName() { return name; } public abstract double getArea(); @Override public String toString() { return name + " (" + String.format("%.2f", getArea()) + ")"; } } public class Circle extends Shape { private final double radius; public Circle(double radius) { super("Circle"); this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } }
import java.util.ArrayList; import java.util.Collections; public class Runner implements Comparable<Runner> { private final String name; private final int seconds; public Runner(String name, int seconds) { this.name = name; this.seconds = seconds; } // Faster runners come first @Override public int compareTo(Runner other) { return Integer.compare(this.seconds, other.seconds); } @Override public String toString() { return name + ": " + seconds + " s"; } public static void main(String[] args) { ArrayList<Runner> race = new ArrayList<>(); race.add(new Runner("Lena", 312)); race.add(new Runner("Noah", 298)); race.add(new Runner("Mia", 305)); Collections.sort(race); for (int i = 0; i < race.size(); i++) { System.out.println((i + 1) + ". " + race.get(i)); } } }
Skills Acquired
Technologies and concepts mastered in this module
Key Takeaways
- Hide the details: Private attributes let a class change its internals without breaking other code.
- A setter is a decision: Not every attribute should be changeable from the outside.
- Prefer collections: An ArrayList grows with the data and removes the need for null checks.
- Program against abstractions: A common supertype lets new classes plug in without changing old code.
- Mind == vs. equals(): Comparing references is not the same as comparing contents.