Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an equivalent to #implementedBySubclass in Java?

I have a design question. I have a class hierarchy:

  • AbstractEntity
  • NPC extends AbstractEntity implements LifeForm
  • Player extends AbstractEntity implements LifeForm

There is a method #moveTo(Target target). This method exists currently in both Player and NPC.

The implemetation is the same for both classes. Only one method called (getQueuedActions()) has a different implementation.

So, in theory, the whole method can be implemented at AbstractEntity, and the concrete difference is implemented at the child class level. But the Java compiler says: getQueuedActions() needs to be implemented also at AbstractEntity. I could of course do an instace of check and implement accordinly. But I thought I ask here, for I think I have something wrong here.

Is there a way to implement the method in Java indicating that yes, this does exist at AbstractEntity but look at the concrete (sub-)class for the real implementation? In Smalltalk, you would do ^implementedBySubClass. To explain, #implementedBySubClass is a way of defining a method as abstract at one level of the class hierarchy but still support a certain protocol (or interface) while not having a real implementation.

Is there an equivalent in Java?

like image 528
Snorik Avatar asked Oct 20 '25 20:10

Snorik


1 Answers

This is the difference between a strongly-typed language like Java and a dynamically-typed language like Smalltalk.

In Smalltalk, you can rely on convention to glue things together, and if something breaks, the developer needs to debug it and figure out why (they'd likely see an error with #subclassResponsibility).

Java needs to know at complile time what classes can or can't do. So in your case, it's complaining that you're expecting your abstract class to understand/implement a method, but only the subclasses understand it - and you could in future be adding other concrete subclasses whose instances don't implement the method.

So one approach you could take in Java would be to implement the method in the abstract superclass, but throw an exception - either a custom one, or something like java.lang.UnsupportedOperationException. The subclasses can then override that method to provide their specific implementations. That way, each instance behaves correctly, and the compiler is happy. If you were to add a new concrete subclass that doesn't override the method, you'd get your exception at runtime if you tried to call that method - which would tell you that you need to implement it.

like image 190
Amos M. Carpenter Avatar answered Oct 22 '25 10:10

Amos M. Carpenter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!