Help with interfaces and abstract classes

So I’m working on a program to control real world light fixtures. I have made a class for each type of light that encompasses all the traits of the fixture type and then an instance is created for each of the real word lights. I then needed a way to be able to reference these lights, which are a mix of classes, so the user could say pick a light from a list. I found this could be done with an interface, which I have never used before. And I also learned setters and getters were needed to get variables in and out of the objects. So now if I manually added a new light into the code, other code such as a selection list could be dynamic in a way by saying something like fixture[n].getName();

I have a lot of common parameters that are used in each fixture type (class) such as the name of the fixture or various integer parameters. For the simplified code below, let’s say all fixtures have a foo but foo is unique for each instance/object. (not static?) I then have identical getters in each class.
As my list of unique fixtures increases and more functions are added to each class. I find myself doing a lot of copy and pasting. If something changes in one class, it has to be changed in all the others so it can be referenced by fixture[x].

So my question is. In the same way that you have functions and variables in a class which apply to all objects, can you sort of do the same with the interface? I’m not sure that even makes sense but an example would be…
Let’s say I want to change doStuff() to {return foo * var + 1;}
I have to go an make that change in each class. Is there a way to have a single doStuff for the whole interface? foo and var could/would also be declared once in the interface?

I tried treating the interface like a class in terms of adding functions/variables to it but that didn’t work. Something about abstract methods. Is there some sort of nested class kind of thing I could do instead?

Just did some googling before posting and have learned about abstract classes and “extends” which seems to do what I need for the functions and variables but then I do not understand how to get all the objects into a single array as I can with the interface. Would I maybe put the abstract parent class into an interface? Now I’m really confused!

interface Fixtures {
  int getVar();
  int getFoo();
}

Fixtures[] fixture = new Fixtures[2];

void setupFixtures()
{
  fixture[0] = new SuperLight(10);
  fixture[1] = new AwesomeLight(20);
}


class SuperLight implements Fixtures
{
  int var;
  int foo = 111;

  SuperLight(int _var)
  {
    var = _var;
  }

  int getVar() {
    return var;
  }

  int getFoo() {
    return foo;
  }

  int doStuff() {
    return foo * var;
  }
}

class AwesomeLight implements Fixtures
{
  int var;
  int foo = 222;

  AwesomeLight(int _var)
  {
    var = _var;
  }

  int getVar() {
    return var;
  }

  int getFoo() {
    return foo;
  }
  
  int doStuff() {
    return foo * var;
  }
}

For simplification you could just toss the interface and instead go w/ the abstract class idea where you’d place the default behaviors for all its subclasses: :bulb:

// Discourse.Processing.org/t/help-with-interfaces-and-abstract-classes/27424/2
// 2021-Jan-28

final Fixture[] fixtures = new Fixture[2];

void setup() {
  fixtures[0] = new SuperLight(10);
  fixtures[1] = new AwesomeLight(20);

  printArray(fixtures);
  exit();
}

abstract class Fixture {
  int foo, bar;

  Fixture(final int val) {
    bar = val;
  }

  int doStuff() {
    return foo * bar;
  }

  String toString() {
    return "foo: " + foo + TAB + "bar: " + bar;
  }
}

class SuperLight extends Fixture {
  SuperLight(final int val) {
    super(val);
    foo = 111;
  }
}

class AwesomeLight extends Fixture {
  AwesomeLight(final int val) {
    super(val);
    foo = 222;
  }
}