Classes

We finally arrive at the heart of the matter.

Warm-up questions

What is the relationship between an object and a class? “An object is an ______ of a class.”

How many instances of a single class can there be?

What is a class?

As in “classification”.

Allows us to classify the parts of our program.

Which allows us to think about collections of values and behavior as cohesive things.

Remember this?

public double distance2d(double x1,
                         double y1,
                         double x2,
                         double y2)
{
  // Yeah, I didn't tell you about hypot at the time. Sorry.
  return Math.hypot(x1 - x2, y1 - y2);
}

The four arguments were really specifying two points.

It’d be nice if we could bundle them up somehow.

Something like this

public double distance2d(Point p1, Point p2) {
  double xDist = p1.getX() - p2.getX();
  double yDist = p1.getY() - p2.getY();
  return Math.hypot(xDist, yDist)
}

It'd also be nice to be able to return a Point as a single value

public Point midpoint(Point p1, Point p2) {
  double avgX = (p1.getX() + p2.getX()) / 2;
  double avgY = (p1.getY() + p2.getY()) / 2;
  return new Point(avgX, avgY);
}

Or maybe make an array of Points

Point[] path = { new Point(0, 0), new Point(10, 20), ... };

A class is another kind of abstraction

Lets us treat a collection of data and behavior as a single thing.

Hides the details of exactly how data is represented.

Hides details of how the behavior is achieved.

Four parts to a class

  • Name

  • Variables

  • Constructors

  • Methods

Class names

The rules for class names are technically the same as for variable and method names.

However they are always capitalized by basically unbreakable convention.

And when you work with actual files, the filename and the class name must match with the filename having a .java extension. So the class Foo will be defined in a file called Foo.java.

Variables

public class Point {

  private double x;
  private double y;

  // ...
}

Variables define the data that make up each instance of the class.

They are declared at the top level of the class.

We’ll talk about what the private before the type means in a few slides.

Constructor, part I

public class Point {
  // ...

  public Point(double x, double y) {
    this.x = x;
    this.y = y;
  }
}

Like a method but with no return type and always named the same as the class.

Job is to initialize the instance variables into a useful state.

Constructor, part II

public class Point {
  // ...

  public Point(double x, double y) {
    this.x = x;
    this.y = y;
  }
}

Note: this is a special variable that is automatically defined in constructors and instance methods as a name for the current object.

Here we use it to disambiguate between the instance variable and the constructor's parameters.

Methods

public class Point {
  // ...

  public double getX() {
    return x; // this refers to the instance variable x
  }

  public double getY() {
    return y; // this refers to the instance variable y
  }
}

These methods are simple “getters” that just allow us to access the values of the private instance variables.

You don’t have to write getters for every instance variable. Some can be kept truly private.

Methods, cont'

public class Point {
  // ...

  public double distanceTo(Point other) {
    return Math.hypot(other.x - x, other.y - y);
  }
}

Within a class we can access the instance variables of other instances of the same class directly, with the dot operator, even when they are private.

Methods, cont’

public class Point {
  // ...

  public void move(double dx, double dy) {
    x += dx;
    y += dy;
  }
}

Methods can change the state of the object by changing its instance variables.

Following the rule to distinguish methods that compute values from those that have effects, state-changing methods are usually void methods.

In some other class

Point p1 = new Point(10, 20);
Point p2 = new Point(100, -100);

System.out.println("distance: " + p1.distanceTo(p2));

p1.move(20, -30);

System.out.println("new distance: " + p1.distanceTo(p2));

We invoke the constructor and the distanceTo and move methods of the Point class.

But we don’t directly access the instance variables because they are private.

Access modifiers

Access modifiers are statements about what code is allowed to access the parts of a class.

public means that code in other classes can access that part or the class.

private means that only code within the class can access that part.

Typically instance variables are private, methods and constructors are public and classes themselves are public.

Two Points in memory

Point p1 = new Point(10, 20);
Point p2 = new Point(100, -100);
p2.move(10, 20);

new makes a new object in memory marking what class it is and reserving room for its instance variables.

The constructor sets x …

… and y.

Then the variable p1 gets a cell of its own.

p1 is assigned a reference to the new object.

Constructing a second object of the same class allocates and initializes its own memory.

The constructor sets x …

… and y.

Then the variable p2.

p2 refers to the second object: two variables, two objects.

p2.move changes the x of the object p1 refers to …

… and its y. The other object is untouched.

Drawn by the content build (build/memory-diagrams.ts) from a <memory> in materials/slides/java/classes/slides.deck Point x: 0.0 y: 0.0 x: 10.0 y: 20.0 p1 Point x: 0.0 y: 0.0 x: 100.0 y: -100.0 p2 x: 110.0 y: -80.0

Questions

There are four parts to a class. What’s one?

What’s another?

And another?

And what’s the last one.

What part of a class defines the structure of the data that makes up an object?

How do we create a new instance of a class?

What part of a class is responsible for initializing an object’s instance variables?

What part of a class defines the behaviors that an object supports?

How can we tell a constructor apart from a method?