165. Creating an electrical panel (hierarchy of classes)
Let’s assume that we want to model in code lines an electrical panel. Of course, we are not electricians, so in a simple vision, an electric panel is a box with some internal circuits made of electrical components and a breaker that turns on/off the electrical panel.

Figure 8.1 – Electrical panel components
Everything in an electrical panel can be considered an electrical component, so we can start our code by defining an interface that must be implemented by everything in this panel:
public interface ElectricComponent {}
Before continuing, let’s have a diagram of the electric panel interfaces and classes meant to follow what comes more easily:

Figure 8.2 – The model of the electrical panel
An electrical panel consists of more electrical circuits that interact (or do not interact) with each other. We can represent such a circuit via an abstract class as follows (this act as a base class for its subclasses):
public abstract class ElectricCircuit
implements ElectricComponent {
public abstract void on();
public abstract void off();
}
Let’s assume that our electrical panel is made of three types of circuits. We have short circuits, series circuits, and parallel circuits. So, we can define the proper class for each type of circuit by extending the abstract ElectricCircuit (we list here only the ShortCircuit, while the ParallelCircuit and SeriesCircuit are available in the bundled code):
public class ShortCircuit extends ElectricCircuit {
public ShortCircuit(ElectricComponent… comp) {}
@Override
public void on() {}
@Override
public void off() {}
}
Check out the constructor of the ShortCircuit class. It gets a varargs argument of type ElectricComponent. This means that we can build a bigger circuit from smaller circuits and other components such as capacitors, transistors, resistors, and so on. Each such electrical component can be shaped via an abstract class. For instance, a capacitor is a base class that can be expressed as follows:
public abstract class Capacitor
implements ElectricComponent {}
We need two types of capacitors (ceramic capacitors and electrolytic capacitors). A ceramic capacitor can be shaped as follows:
public class CeramicCapacitor extends Capacitor {}
Following the same logic, we can express other electrical components such as transistors (Transistor (abstract), BipolarTransistor, FieldEffectTransistor) and resistors (Resistor (abstract), CarbonResistor, MetalResistor, and its two subtypes, MetalFilmResistor and MetalOxideResistor).We almost have all the needed electrical components for building our panel. We just need the electrical breaker which is just another electrical component with the particularity that it exposes two methods for turning on/off the electrical panel:
public interface ElectricBreaker extends ElectricComponent {
void switchOn();
void switchOff();
}
And, finally, we can materialize the electrical panel as follows (we assume that we have three circuits, a central circuit, a peripheral circuit, and an auxiliary circuit):
public class ElectricPanel implements ElectricBreaker {
private final ElectricCircuit centralCircuit;
private final ElectricCircuit peripheralCircuit;
private final ElectricCircuit auxiliaryCircuit;
public ElectricPanel() {
peripheralCircuit = new SeriesCircuit(
new ElectrolyticCapacitor(),new ElectrolyticCapacitor(),
new MetalFilmResistor(), new CarbonResistor());
auxiliaryCircuit = new ShortCircuit(
new CeramicCapacitor(), new ElectrolyticCapacitor(),
new MetalResistor(), new FieldEffectTransistor(),
new FieldEffectTransistor());
centralCircuit = new ParallelCircuit(
peripheralCircuit, auxiliaryCircuit,
new CeramicCapacitor(), new BipolarTransistor(),
new MetalOxideResistor());
}
@Override
public void switchOn() {
auxiliaryCircuit.off();
peripheralCircuit.on();
centralCircuit.on();
}
@Override
public void switchOff() {
auxiliaryCircuit.on();
peripheralCircuit.off();
centralCircuit.off();
}
}
Done! Now, a client of our panel can operate it via the switchOn()/switchOff() methods:
ElectricPanel panel = new ElectricPanel();
panel.switchOn();
In the next problem, we will see how we can close this hierarchy of classes in order to increase encapsulation and avoid accidental/non-accidental extensions.