Memra

Abstract classes & methods

Partially-implemented base classes that define a contract subclasses must complete.

A base class that cannot be instantiated

Sometimes a base class exists only to define a common shape for its subclasses — it has no meaningful standalone object. In the Greenhouse control system, every control action (turn the light on, open the water, ring the bell) *is an* Event, but there is no such thing as a bare "Event" object — the *what to do* differs for each kind. Java models this with an abstract class.

An abstract class:

- is declared abstract and cannot be instantiatednew Event(1000) is a compile error; - may contain ordinary fields, constructors, and fully-implemented methods (shared behaviour); - may contain abstract methods — a method signature with no body, ending in a semicolon, that every concrete subclass is forced to override.

If a class has even one abstract method it MUST be declared abstract. The compiler then guarantees that any *concrete* (non-abstract) subclass supplies a body for every inherited abstract method, so callers can rely on the method existing.

Worked example — the project's Event

public abstract class Event {
  private long eventTime;
  protected final long delayTime;

  public Event(long delayTime) {
    this.delayTime = delayTime;
    start();
  }
  public void start() {                 // shared, concrete
    eventTime = System.currentTimeMillis() + delayTime;
  }
  public boolean ready() {              // shared, concrete
    return System.currentTimeMillis() >= eventTime;
  }
  public abstract void action();        // abstract — no body
}

Notice the mix: Event carries real state (eventTime, delayTime), a constructor, and two concrete methods (start, ready) that every event shares — but action() is abstract because *what the event does* is different for each subclass. A subclass becomes concrete only by implementing action():

class Bell extends Event {
  public Bell(long delayTime) { super(delayTime); }
  public void action() { /* ring */ }   // now concrete
}

Because Event has an abstract method, you can declare a variable of type Event and hold any subclass through it (Event e = new Bell(1000);) — but you can never write new Event(...).

NORMAL ~/memra/learn/comp-308/abstract-classes-and-methods utf-8 LF