I've been studying java a little bit and I've come upon a problem I couldn't solve (I did research but since it's a pretty specific question no answer was found):
I'm trying to add variables and methods that would be inherited by classes in the same way an interface does it (have a class inherited by different classes that already have an ancestor, i.e.: Actor extends Character and Weapon extends Item, I need both Actor and Weapon to have XY coordinates, width/height and move() method)
At first I thought Interfaces were the solution, but since they are 100% abstract, I would need to redefine the methods every time, which, to me, beats the purpose of inheritance in this case.
I have thought about making a superior parent (like MovableObject) at the root of the ancestry tree which would include both the Item and Actor classes, but since they are so different in every other way it feels counter logic to have them in the same ancestry tree.
Thank you all for your responses, I said I'd update when I tried it, and I did but now I realize my whole code is going to need a lot of refactoring so I can't tell you if it works or not right away. Although it did solve my problem since I at least have something to work towards.
The language constructs that you can use are either interfaces or abstract classes.
getPrice
in Item
and inherit that in Weapon
).In your example, methods such getWidth()
, getHeight()
, getX()
and getY()
are good candidates for interfaces (since they share some common traits between unrelated objects).
// Another way to share this state would be via a Point interface and
// aggregating two point objects in your Item and Character classes
interface Coordinates {
double getX1();
double getY1();
double getX2();
double getY2();
}
interface Dimension {
double getWidth();
double getHeight();
}
I don't know your whole context, but are you sure you need both coordinates and dimensions (I think you could determine the width and height from the X and Y)?
Those interfaces should be implemented by both of your ancestor classes (Character
and Item
) and inherited through the hierarchy. Do not add a common ancestor between Character
and Item
just so you can avoid implementing getX
and getY
twice.
Regarding the move
method, I think it's another responsibility and you should define it somewhere else.
// Not necessarily the right name
class MoveHelper {
// You can pass either a Character or an Item here
// since both implement Coordinates
// Not necessarily the right signature
void move (Coordinates object)
}
Depending on how you chose to design your solution, the move
method can become a static
somewhere or an object that you would aggregate in both Character
and Item
and delegate to it for the move
implementation.
As a final note, consider that you can achieve reuse via either inheritance (interfaces and abstract classes) or composition (what you would do if you would aggregate the MoveHelper
and delegate to it for the move
implementation in Character
and Item
).
Hope this helps!