I'm experiencing difficulties setting up the structure of my code. In one project, I have two classes LeftCell
and RightCell
, both extending class Cell
. Now, to avoid code duplication, I want to use these objects in multiple other projects. The problem is that I also want to add extra functionalities to these objects (the Cell
object in particular), which differ per project.
Suppose I create a new project in which I want to visualize Cell
objects using a void draw()
method. My first thought was to create a new CellProject1
class that extends the Cell
class and includes the draw()
method:
class CellProject1 extends Cell {
void draw() {}
}
The problem is that any LeftCell
/RightCell
objects I create, do of course not have access to this draw()
method. I guess I want to somehow squeeze a Cell
subclass in the class hierarchy such that it changes from:
Cell
LeftCell
RightCell
to:
Cell
CellProjectX
LeftCell
RightCell
depending on the project I'm running. I played around with generics, but can't get it to work. All suggestions are welcome!
The problem is that any LeftCell/RightCell objects I create, do of course not have access to this draw() method.
A method specific to a child class can not of course be invoked on a parent instance that doesn't know it.
Since your requirement is
Inheritance hierarchy altering to reduce code duplication In one project, I have two classes LeftCell and RightCell, both extending class Cell. Now, to avoid code duplication, I want to use these objects in multiple other projects
I think that you should make things a little different.
If you want to avoid exploding the number of combination possible of classes and not duplicating LeftCell
and RightCell
like in your example :
Cell
CellProjectX
LeftCell
RightCell
that could be finally completed by :
Cell
CellProjectY
LeftCell
RightCell
Cell
CellProjectZ
LeftCell
RightCell
you should favor the composition over the inheritance to create your specific project Cell
implementations.
For the common Cell structures:
The Cell
subclass could be a Cell
interface that define common methods for any Cell
and you could have a AbstractCell
class that defines common implementation for it.
public interface Cell{
int getValue();
void setValue(int value);
}
public abstract class AbstractCell implements Cell{
...
}
Then you could define the RightCell
and LeftCell
by extending AbstractCell
:
public class RightCell extends AbstractCell {
...
}
public class LeftCell extends AbstractCell {
...
}
For the Cell implementations specific to a project :
Now in a specific project you could a create a custom Cell
implementation by composing it with a Cell
instance (finally a LeftCell
or RightCell
instance) that will under the hood be used to implement the Cell
interface in the specific project concrete class.
In the specific implementation, you could of course add any required method specific to the project.
For example :
class CellProject1 implements Cell {
private Cell cell;
CellProject1 (Cell cell){
this.cell = cell;
}
public int getValue(){
cell.getValue();
}
public void setValue(int value){
cell.setValue(value);
}
public void draw(){
...
}
}
You can so create CellProject1
instances like that :
CellProject1 leftCell = new CellProject1(new LeftCell());
CellProject1 rightCell = new CellProject1(new RightCell());
leftCell.draw();
rightCell.draw();
And in another project that uses CellProject2
instances with a specific write()
method, you could write :
CellProject2 leftCell = new CellProject2(new LeftCell());
CellProject2 rightCell = new CellProject2(new RightCell());
leftCell.write();
rightCell.write();