3

I have following class inheritances (A is my parent class):

enter image description here

In some cases, X and Y need some extra fields and methods. So what I basically need is this:

enter image description here

I don't want to extend X and Y to give their child classes exact the same fields and methods due to duplicate code.
How to handle this? Is the only solution a delegate?


Update: Real-world example:

I'm importing data from different file types:

Package my_application.core:

public class ImportFile { // the "A"
  protected final Path path;
}

public class CsvImportFile extends ImportFile { // the "X"
  private final String delimiter;
}

public class FixedLengthImportFile extends ImportFile { // the "Y"
  // nothing new
}

public class XmlImportFile extends ImportFile {
  private final String root;
}

Sometimes the first lines of a file contain heads/titles instead of data. So here an example extension which allows to set a start line for csv and fixed-length files:

Package my_application.extension.line_start:

public class ExtensionLineStartImportFile { // the "B"
  protected final int lineStart;
  // some methods
}

So if the user chooses to use the extension line_start, CsvImportFile and FixedLengthImportFile should get the properties of ExtensionLineStartImportFile.

Side node: Since I have multiple extensions which do different things and these extensions should be easy to add to/remove from the application, I don't want to merge them all into the "core".

halloei
  • 1,892
  • 1
  • 25
  • 45
  • "don't want to extend X and Y to give their child classes exact the same fields and methods due to duplicate code." -- what duplicate code? – Stultuske Sep 28 '15 at 12:28
  • `X` and `Y` would need the same fields and methods. If I create a subclass for both of them, I'd write the same code twice. – halloei Sep 28 '15 at 12:29
  • duplicate code means which is inherited from A? – Avinash Sep 28 '15 at 12:30
  • 3
    and where do you duplicate that code, that code is within the parent class, not the subclasses – Stultuske Sep 28 '15 at 12:33
  • @Avinash: Uhm, no. I'm sure I can't do it like in figure 2 because then `X` and `Y` would **always** have the fields and methods of `B`. Since I need it conditionally, a solution is to extend `X` and `Y`. That would result in duplicate code. – halloei Sep 28 '15 at 12:33
  • What kind of condition are you talking about? You can't have a class that sometimes has certain methods and doesn't at other times. It would help if you'd be more specific about the "in some cases" here, ideally with a realistic example. – Jon Skeet Sep 28 '15 at 12:34
  • @Jon Skeet: I'm writing some kind of extension for my application. The extension requires `X` and `Y` to have the fields and methods of `B`. Since it's an extension, I don't want always to inherit from `B`. – halloei Sep 28 '15 at 12:38
  • That doesn't give any indication of the "condition" in this case. – Jon Skeet Sep 28 '15 at 12:38
  • @halloei: "a solution is to extend X and Y", this is not possible in Java. – Stultuske Sep 28 '15 at 12:40
  • @Jon Skeet: The user chooses either to start the default mode or the extension of my application. Is that what you wanted to know? @Stultuske: I meant creating a subclass for each (like `XSub` and `YSub`) instead of inheriting from `B` – halloei Sep 28 '15 at 12:42
  • 3
    As others stated, the question is not very clear, but there's a general recommendation, which might get you further: prefer composition over inheritance. – Puce Sep 28 '15 at 12:44
  • 1
    It sounds like you should use composition rather than inheritance in both cases, yes. It's not really clear what you mean by "extension" in this case. – Jon Skeet Sep 28 '15 at 12:44
  • @halloei: by creating subclasses of x and y, what difference do you think it 'll make? – Stultuske Sep 28 '15 at 12:47
  • Could you make `B` an interface? Then you could have subclasses of `X` and `Y` that implement `B` when `X` and `Y` do not. – Paul Boddington Sep 28 '15 at 12:48
  • I've written multiple "extensions" and each has its own package. My goal is to modify my default application with them in different ways to change its behaviour. My application extracts, formats and outputs data from different file formats (like csv, xml, ..). – halloei Sep 28 '15 at 12:52
  • 1
    I'm going to make a guess based on your still-incomplete information: you have an overall problem that cannot be solved with either inheritance or composition. You need to take an entire step backwards and look at the overall problem, and either describe it to us or to someone familiar with OO tools, and solve the problem by itself instead of attempting to solve-the-problem-with-inheritance. – arcy Sep 28 '15 at 12:56
  • 1
    A real-world example would help. – biziclop Sep 28 '15 at 12:59
  • Thanks so far. I added an example. – halloei Sep 28 '15 at 13:35

2 Answers2

1

Factory pattern - this is quite an architectural issue and this pattern should be the answer for Your problem

Lemonov
  • 476
  • 4
  • 17
0

You cannot have "conditional inheritance" in Java. Either you extend a class, either you don't. Changing the legacy chain implies recompiling the application.

If a C extends B extends A but B is not on the classpath, the class loading of C will fail.

The only solution I see here is to integrate this logic into your code (or have as many implementations as there are possible combinations).

So, yes, delegates would be a way (probably the only one to have logic on your classpath only when you need it). Having multiple ugly ifs in your code is another.

Chop
  • 4,267
  • 5
  • 26
  • 58