Getting (back) into Java, Part 2
1 Getting (back) into Java, Part 2

Getting (back) into Java, Part 2

CS 3500, Spring 2024

Recap from last time

  • Designed interface Duration

  • Implemented it as class DurationImpl

  • But used a silly representation:

    private final int hours;
    private final int minutes;
    private final int seconds;

What we'd like to do now

  • Use a less-silly representation:

    private final long inSeconds;

What are our options?

We made one bad decision

But we also made two good decisions:

  • Information hiding (can change representation because fields are private)

  • Interface polymorphism (code that uses the Duration interface will work with future implementations of it)

Let's explore the latter

Code time

DurationImpl:

public Duration plus(Duration d) {
  return new DurationImpl(inSeconds() + d.inSeconds());
}

CompactDuration:

public Duration plus(Duration that) {
  return new CompactDuration(inSeconds() + d.inSeconds());
}

AbstractDuration:

public Duration plus(Duration d) {
  return new ❓❓❓(inSeconds() + d.inSeconds());
}

A design pattern

Problem

Superclass doesn't know what class to construct, but subclasses do

Solution

Factory method pattern, in which the superclass

  • defers object construction to subclasses

  • by declaring an abstract factory method

  • that subclasses must implement.

DurationImpl:

public Duration plus(Duration d) {
  return new DurationImpl(inSeconds() + d.inSeconds());
}

CompactDuration:

public Duration plus(Duration that) {
  return new CompactDuration(inSeconds() + d.inSeconds());
}

AbstractDuration:

public Duration plus(Duration d) {
  return fromSeconds(inSeconds() + d.inSeconds());
}


DurationImpl:

public Duration plus(Duration d) {
  return new DurationImpl(inSeconds() + d.inSeconds());
}

CompactDuration:

public Duration plus(Duration that) {
  return new CompactDuration(inSeconds() + d.inSeconds());
}

AbstractDuration:

public Duration plus(Duration d) {
  return fromSeconds(inSeconds() + d.inSeconds());
}

protected abstract Duration fromSeconds(long);

DurationImpl:

public Duration fromSeconds(long s) {
  return new DurationImpl(s);
}

CompactDuration:

public Duration plus(Duration that) {
  return new CompactDuration(inSeconds() + d.inSeconds());
}

AbstractDuration:

public Duration plus(Duration d) {
  return fromSeconds(inSeconds() + d.inSeconds());
}

protected abstract Duration fromSeconds(long);

DurationImpl:

public Duration fromSeconds(long s) {
  return new DurationImpl(s);
}

CompactDuration:

public Duration fromSeconds(long s) {
  return new CompactDuration(s);
}

AbstractDuration:

public Duration plus(Duration d) {
  return fromSeconds(inSeconds() + d.inSeconds());
}

protected abstract Duration fromSeconds(long);