0

The title might be a little confusing, but let me explain what I mean. I'm trying to create classes that all have the same base fields, but then each of the classes has fields that are shared by some, but not all like this:

abstract class BaseClass {
    private final int a;
    private final int b;
    private final int c;
}

class A extends BaseClass {
    private final int j;
    private final int y;
}

class B extends BaseClass {
    private final int j;
    private final int x;
}

class C extends BaseClass {
    private final int k;
    private final int y;
}

class D extends BaseClass {
    private final int k;
    private final int x;
}

I also drew up a little diagram to illustrate what I'm trying to accomplish

Now I know that what I'm describing here is multiple inheritance, but unfortunately (or fortunately I suppose, depending on your perspective) Java doesn't support multiple inheritance. That leaves me with 2 options:

  1. Just duplicate the fields wherever I need them like in the example above

  2. Put the properties into separate classes which then become the fields in the concrete classes like this:

abstract class BaseClass {
    private final int a;
    private final int b;
    private final int c;
}

class PropertiesClassJ {
    private final int j;
}

class PropertiesClassK {
    private final int k;
}

class PropertiesClassX {
    private final int x;
}

class PropertiesClassY {
    private final int y;
}

class ConcreteClass1 extends BaseClass {
    private final PropertiesClassJ propertiesClassJ;
    private final PropertiesClassK propertiesClassK;
}

class ConcreteClass2 extends BaseClass {
    private final PropertiesClassJ propertiesClassJ;
    private final PropertiesClassX propertiesClassX;
}

Obviously option 1 is not really the way to go, but I don't really like option 2 either since it doesn't really match the structure that the final object is trying to represent. Is there another option here to get what I want, or is option 2 my best choice?

Jacob
  • 1
  • What makes the most "sense" is context-dependent, the biggest differentiator being whether or not a given variable matters outside of the instance (e.g., are "all things with `x`" the "same"). On the surface I see little value in composition if they *are* the same, but that also depends on what `x` means to each containing class. I doubt there's enough information here to provide meaningful advice, but I may be missing something. – Dave Newton Mar 14 '22 at 18:57
  • 1
    You can apply the Interface segregation pattern from the SOLID principles. E.g. an interface `HasJ { int getJ(); }`, another `HasK { int getK(); }`. Now write your classes like for example `Class A extends BaseClass implements HasJ, HasK, ...`. You still need to provide the implementation of `getJ()`, `getK()` etc. If however your classes can become interfaces themselves, you can utilize [Immutables](https://immutables.github.io/) to auto-generate the implementation. Hey, your classes are already immutable, so this is a win-win situation. – Nikos Paraskevopoulos Mar 14 '22 at 18:59
  • For additional context, I'm trying to implement the New Order Single object from the [FIX message protocol](https://btobits.com/fixopaedia/fixdic42/index.html). So for example a LIMIT order would require different fields than a MARKET order, and an SS&C order would have different fields than a Instinet order. So I could have an InstinetMarketOrder and an SSCMarketOrder, and then I could have a InstinetLimitOrder and an SSCLimitOrder. Also these fields apply directly to the order and that's why I feel like grouping them in separate classes doesn't make the most sense @DaveNewton – Jacob Mar 14 '22 at 19:24
  • I find Lombok's `@Delegate` feature an interesting solution to the common problem of code reuse among data structures, which according to [conventional wisdom](https://stackoverflow.com/questions/49002/prefer-composition-over-inheritance) is a problem that inheritance is unsuited for. – jaco0646 Mar 17 '22 at 01:01

0 Answers0