Skip to content

Data classes (course slides + memo)

Java. Covers: methods/behavior on classes, data classes vs service classes, visibility, getters/setters, equals/hashCode/toString.

Methods: classes can have behavior

Object-oriented programming: an object has properties (data) and behavior (methods).

java
public class Car {
    // Properties (fields)
    String color;
    double maxSpeed;

    // Constructor...

    // Behavior (methods)
    public void turnOnLights() {
        System.out.println("Lights have been turned on.");
    }

    public void drive() {
        System.out.println("Car is driving now at maximum speed: " + this.maxSpeed);
    }
}

public class Main {
    public static void main(String[] args) {
        Car carOne = new Car("black", 250);
        carOne.drive();
        carOne.turnOnLights();

        Car carTwo = new Car("green", 120);
        carTwo.drive();
    }
}

Methods without the static keyword:

  • are defined inside a class
  • can only be called on concrete instances of that class
  • can have parameters and return types, just like any other method
  • can use the properties of the class they are defined in

The two types of classes

Most of programming is modifying information. To modify information you need classes that represent data, and classes that modify it.

Analogy: a car factory receives car pieces and workers who assemble them. Same split in code:

  • Data classes — represent the information of the application.
  • Service classes — represent the workers modifying that information.

Keeping service-class logic clearly separated from data-class information is the whole point of the split.

Data classes

java
public class Person {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// Elsewhere:
Person person = new Person("John", 30);
System.out.println(person.name);
person.age = 31;

Visibility modifiers

Making fields private means they can't be accessed or modified from outside the class:

java
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// Elsewhere:
Person person = new Person("John", 30);
System.out.println(person.name); // Compiler error: name is private
person.age = 31; // Compiler error: age is private

Getters and setters

  • getters are public methods that grant access to the private properties we want to expose. One per property we want to offer.
  • setters are public methods that allow changing a private property's value after creation. One per property we want to allow changing afterward.
java
public class Person {
    private String name;
    private int age;
    // (... constructor with arguments ...)

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

// Elsewhere:
Person somebody = new Person("Lisa", 27);
String name = somebody.getName();
somebody.setName("Veronica");

Recap: visibility

  • Properties in classes should almost always be private.
  • A private property can't be read or written to by other classes.
  • A public getter allows a private property to be read by other classes.
  • A public setter allows a private property to be written to by other classes.

Exercise (as given)

Pick an exercise from a previous week with multiple classes, copy it to a new package:

  1. Refactor all classes' properties to private.
  2. Add getters, setters, hashCode, equals, and toString to the classes.
  3. Rewrite the rest of the code so everything still works.
  4. Print an instance of a class to check the toString override.
  5. Create two instances with identical field values; compare them with equals in an if statement. Try it once with equals/hashCode commented out to see the difference.

Memo additions (constructors, in more detail)

The constructor is a method without a return type that must have the same name as the class, and may take arguments.

  • this references the object itself — useful when a constructor argument has the same name as the class's property, so you don't need to rename it to something like name1.
  • A class can have more than one constructor.
  • If you don't provide a constructor, Java provides an empty one by default — but using the empty one is considered bad practice once a class has properties, since it can produce invalid/incomplete objects (e.g. a Person with no name or age).
  • Once you provide a constructor with arguments, the implicit empty constructor is not generated anymore.
java
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// Elsewhere:
Person somebody = new Person("Lisa", 27);