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).
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
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:
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 privateGetters 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.
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:
- Refactor all classes' properties to
private. - Add getters, setters,
hashCode,equals, andtoStringto the classes. - Rewrite the rest of the code so everything still works.
- Print an instance of a class to check the
toStringoverride. - Create two instances with identical field values; compare them with
equalsin anifstatement. Try it once withequals/hashCodecommented 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.
thisreferences 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 likename1.- 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
Personwith no name or age). - Once you provide a constructor with arguments, the implicit empty constructor is not generated anymore.
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);