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, such as in Codespaces, 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;

  // ...
}

Define the data that each instance of the class has.

Declared at the top level of the class.

Just like normal variable declarations but can have an access modifier like public or private

Usually instance variables are private.

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 construtor’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.

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?