Why is the following interface contract not allowed? - java

I'm thinking about offering a new feature to Java and I would like to ask why have it been restricted by design so far:
public abstract class BodyPart {
abstract public void followBodyPart(BodyPart part);
}
public class Head extends BodyPart{
public void followBodyPart(Body body ) { //Why is this kind of implementation not allowed?
...
}
}
public class Body extends BodyPart{
public void followBodyPart(Head head ) { //and this
...
}
public void followBodyPart(Forearm leftForearm ) { //and also this
...
}
...
}
//Arm, Forearm, etc...
Why is followBodyPart(Body body) in Head not implementing followBody in BodyPart? If it would, the advantages would be clear.
Firstly, the IDE would be able to offer within it's autocomplete feature Body objects as parameters to followBody instead of any other BodyParts objects that Head can not follow.
Secondly, the current version of Body consists of one function and many instanceof's, which could be eliminated.
Finally, generics can help here but not solve the problem, since this code should be ported to Java ME devices.
This question was already asked, in the not appropriate forum as I discovered here
In regards to the answers, I invite you to think different. I understand that anything implementing BodyPart should accept any BodyPart, but: what I want is to be able to say that Head would be able to accept A BodyPart to follow.
Thanks.

The question was also answered in the forum post you linked..
Namely; the interface defines the function should be able to accept anything that implements BodyPart.
By implementing the function in Head to only accept the subclass Body, but not any other subclass; you are violating that contract (since it no longer accepts anything implementing BodyPart).
Interfaces are usually used to provide to "external" code, allowing them to be sure that, whichever implementation of the interface is provided; they can for sure use the functions defined by the interface.
So if this external code gets an BodyPart, it knows it has a function followBodyPart that can accept anything extending BodyPart as argument. That external code will, however, never know that it got Head (or can, after casting it after an instanceof check) and thus cannot know that the interface function will only accept a Body.
By request; say that you provide the BodyPart interface as some kind of program API. In that case, I do not directly need to know what type of BodyPart it is. Now say that I have two of them; received through some functions in your API, for example with the signature: public BodyPart getBody(). The method states it might be a Body I get back; but it could as well be something else (fact is, I don't know!).
According to the BodyPart interface; I can call followBodyPart on the first BodyPart, and pass the second one in as argument. However, the actual Body implementation would not allow this; and there is no way for me to know that.
If you really want different classes to accept different entries; you should either drop the function from BodyPart and just implement it in the subclasses.
By passing those subclasses back from the API; everyone knows what they're talking with, and what it can do (e.g. public Body getBody() and public Head getHead()). Since I then have the actual implementation classes, which have the actual implementation with a certain BodyPart to 'follow', it isn't a problem.
An other option would be - but stated impossible in your question - to use generics; in such case you can define an Interface stating:
public interface Accepts<T extends BodyPart> {
public void followBodyPart(T part);
}
And the API could pass back either the implemented BodyPart, or an Accepts<Head> instance, for example.
(Edit: as I wrote this here, I forgot to keep in mind you cannot implement the same interface more then once with different generic types; so the generic interface method would need the actual implementation to encapsulate objects that can actually handle the calls, making everything even more a mess)
Bonus edit: ofcourse you can also make AcceptsHead, AcceptsArm as interfaces and effectively working around the generics issue :).
I hope this edit clears up why it would be a weird (and bad) idea to have a generic interface (using BodyPart as argument), but only specify specific implementations in the (possibly hidden) implementation classes.

First of all, I'm not quite intuitively understanding your class relationships - they are circular which is already an indication of a bad design. I'm not saying you don't happen to NEED that particular structure - I would just suggest that some refactoring to remove the circularity might ultimately be a better design.
What it looks like you're trying to do is implement a visitor-pattern. But if you have a reference to the base class, it could never trigger the invocation of the specialized methods - e.g. since the compiler can't pick the method you intended, then the runtime is just going to have to do the instance-of switching for you - it would only be syntactic sugar at best (look up scala, they actually do that).
def bodyPart(part:BodyPart) =>
part match {
Head(h) => /* do something with head h */
Foot(f) => /* do something with foot f */
Toe(t) => /* do something with toe t */
}
The other way to solve this is to abstractly noop all possible visitor types:
public class BodyPart { // could have been abstract class
public void followBodyPart(BodyPart part) { }
public void followBodyPart(Head part) { }
public void followBodyPart(Arm part) { }
public void followBodyPart(Foot part) { }
public void followBodyPart(Toe part) { }
}
public class Head { ... /* only implements Head, BodyPart, others error */ }
public class Arm { ... /* only implements Arm, Abdomen, etc */ }
Now the visitor invoker will staticly choose the correct method at compile time. But it needs more plumbing in each implementation because it needs to decide how to properly handle all the other input types. But that's a good thing - it removes ambiguity.

Related

Proper use of generics in abstract java class?

EDIT: This question is not well worded, and the provided answer is correct in a literal sense but did not teach me how to attain what I needed. If you are struggling with the same problem, this is what finally helped me: How to enforce child class behavior/methods when the return types of these methods depends on the child class?
I am trying to implement a basic matrix class from a boilerplate abstract class I wrote. There will be several implementations of this abstract class, each one using a different math library, which I will then test for speed.
Each implementation will hold its data in that library's native matrix data structure. I think this is a use case for generics. At this point I think I've read too many tutorials and watched too many videos, as I just can't seem to figure out all the right places to put the T Notation to make this work correctly.
So my question is twofold:
Have I misused or missed the point of generics?
If not, what is the correct syntax for their use?
I've read the docs plus about three different tutorials and still can't understand.
Here is what I've tried:
public abstract class BaseMatrix<T> {
protected int[] shape;
protected int nrows;
protected int ncols;
protected T data; // <--- Here is the generic data --->
public BaseMatrix(int rows, int cols){
this.nrows = rows;
this.ncols = cols;
this.shape = new int[]{nrows, ncols};
}
public abstract BaseMatrix mmul(BaseMatrix other);
And here is my implementation:
public class ND4JDenseMatrix extends BaseMatrix{
// private INDArray data;
public ND4JDenseMatrix(int rows, int cols) {
super(rows, cols);
this.data = Nd4j.zeros(this.shape); <--- Here is the non-generic data --->
}
#Override
public ND4JDenseMatrix mmul(ND4JDenseMatrix other) {
ND4JDenseMatrix result = new ND4JDenseMatrix(nrows, ncols);
result.data = data.mmul(other.data);
return result;
}
The error is: Method does not override method from its superclass.
hold its data in that library's native matrix data structure. I think this is a use case for generics.
Generics serves to link things. You declared the type variable with <T>, and you've used it in, as far as your paste goes, exactly one place (a field, of type T). That's a red flag; generally, given that it links things, if you use it in only one place that's usually a bad sign.
Here's what I mean: Imagine you want to write a method that says: This method takes 2 parameters and returns something. This code doesn't particularly care what you toss in here, but, the parameters must be the same type and I return something of that type too. You want to link the type of the parameter, the type of the other parameter, and the return type together.
That is what generics is for.
It may apply here, if we twist our minds a bit: You want to link the type of the data field to a notion that some specific implementation of BaseMatrix can only operate on some specific type, e.g. ND4JMatrix.
However, mostly, no, this doesn't strike me as proper use of generics. You can avoid it altogether quite easily: Just.. stop having that private T data; field. What good is it doing you here? You have no idea what type that is, you don't even know if it is serializable. You know nothing about it, and the compiler confirms this: There is absolutely not one iota you can do with that object, except things you can do to all objects which are generally quite uninteresting. You can call .toString() on it, synchronize on it, maybe invoke .hashCode(), that's about it.
Why not just ditch that field? The implementation can make the field, no need for it to be in base!
public class ND4JDense extends BaseMatrix {
private ND4JMatrix data; // why not like this?
}
(This code assumes 'ND4JMatrix' is the proper data type you desire here, a thing that can is the internal representation for the data in the ND4J impl).
However, if you must, yeah, you can use generics here. You've type-varred BaseMatrix, and that means all usages of BaseMatrix must be parameterized. That's the part you messed up in your code. If we go with your plan of a type-parameterized BaseMatrix class and a field of type T, the right code is:
public class ND4JDense extends BaseMatrix<ND4JMatrix> {
...
}
I wouldn't, however, do it this way (I'd go with having the impl have the field, much simpler, no need to bother anybody with the generics). Unless, of course, you DO have an actual need for that field and it IS part of BaseMatrix's API. For example, if you want this:
public class BaseMatrix<T> {
public T getData() { return data; }
}
then it starts to make more sense. With that, you can write the following and it'll all compile and work great:
public class ND4JDense extends BaseMatrix<ND4JMatrix> {
...
// no need to write a getData method here at all!
...
}
ND4JDense dense = new ND4JDense();
ND4JMatrix matrix = dense.getData();
But, clearly, this makes no sense if you intend for the ND4JMatrix to remain an implementation detail that users of the BaseMatrix API should probably not be touching.
EDIT: You changed the question on me, later. Now you want the mmul method to take 'self' as argument, effectively: You want the same type to be passed in.
You can sort of do that but it is a little tricky. You need the self-ref generics hack. It looks like this:
public class BaseMatrix<T extends BaseMatrix<T>> {
public abstract T mmul(T other);
}
In practice the only valid value for T is your own class, or at least, that is the intent. This works fine:
public class ND4JDenseMatrix extends BaseMatrix<ND4JDenseMatrix> {
public ND4JDenseMatrix mmul(ND4JDenseMatrix other) {
.. impl here ..
}
}
As far as I see, you have two issues in your code:
You're not actually overriding the method of the superclass. What you have created is an overload of method mmul. To correctly override the method, the method signature must match, in particular the input parameter must be the same. It's ok to have a subtype of the return type, as Java support covariant. If you instead put one of its subclass, that is overloading. Hope you get the difference. So the correct signature can be the following:
public BaseMatrix mmul(BaseMatrix other) {
...
}
You have not specified the type T, so the compiler cannot know that by assumption is a subtype of BaseMatrix. it can be any type, even Object for example, so you are going to get "method not found" compilation error.

Drawbacks of explicitly implementing not used interface

I came up with this question writing specific code, but I'll try to keep the question as generic as possible.
Other similar question refer to C# which seems to have some language specific handling for this and below code is Java, but again let's try to keep it generic.
Let's say I have class A which implements interface I.
This is useful to me cause I can implement methods that use A only as a I type and abstract the implementation.
Let's now say, I have class B which implements all methods in interface I, but it's never referred to as only I.
Let's now say, I have class B which implements methods that have the same name/signature as the ones in interface I, but it doesn't implements the interface.
Should I always explicitly implement I?
Even if I don't use it (though I might in the future) for type abstraction?
A more meaningful, even if probably not realistic, example would be:
interface Printable {
String print()
class A implements Printable {
//code...
String print(){return "A";}
//code...
}
class B {
//code...
String print(){return "B";}
void otherMethod(){/*code*/}
//code...
}
class Test {
Printable a = new A();
System.out.println(a.print());
B b = new B();
b.otherMethod();
System.out.println(b.print());
}
Are there any drawbacks on explicitly implementing, or not, the interface Printable?
The only one I can think of is scalability for the second case.
In the sense that if one day I'll want to explicitly use it as Printable, I'll be able to do so without any more effort.
But is there anything else (patterns, optimization, good programming, style, ..) I should take into consideration?
In some cases the type hierarchy will affect the method call cost due to not playing well with JIT method inlining. An example of that can be found in Guava ImmutableList (and others) offer awful performance in some cases due to size-optmized specializations #1268 bug:
Many of the guava Immutable collections have a cute trick where they have specializations for zero (EmptyImmutableList) and one (SingletonImmutableList) element collections. These specializations take the form of subclasses of ImmutableList, to go along with the "Regular" implementation and a few other specializations like ReverseImmutable, SubList, etc.
Unfortunately, the result is that when these subclasses mix at some call site, the call is megamorphic, and performance is awful compared to classes without these specializations (worse by a factor of 20 or more).
I don't think there is a simple correct answer for this question.
However, if you do not implement the method, you should do this:
public void unusedBlahMethod() {
throw new UnsupportedOperationException("operation blah not supported");
}
The advantages of omitting the unused method are:
You save yourself time and money (at least in the short term).
Since you don't need the method, it might not be clear to you how best to implement it anyway.
The disadvantages of omitting the method are:
If you need the method in the future, it will take longer to add it as you may have to refamiliarize yourself with the code, check-out, re-test, etc.
Throwing an UnsupportedOperationException may cause bugs in the future (though good test coverage should prevent that).
If you're writing disposable code, you don't need to write interfaces, but one day you might notice, that you should've taken your time and write an interface.
The main advantage and purpose of interfaces is the flexibility of using different implementations. I can put something, that offers the same functionality inside a method, I can create a fake of it for test purposes and I can create a decorator that behaves like the original object, but can log the stuff.
Example:
public interface A {
void someMethod();
}
public class AImplementation {
#Override
public void someMethod() {
// implementation
}
}
public class ADecorator {
private final A a;
public ADecorator(A a) {
this.a = a;
}
#Override
public void someMethod() {
System.out.println("Before method call");
a.someMethod();
System.out.println("After method call");
}
}
Nice side effect: ADecorator works with every implementation of A.
The cost for this flexibility isn't that high and if your code will live a little bit longer, you should take it.

Abstract vs Empty method

I need to add one optional method in existing abstract class that is extended by more than 50 classes:
public abstract class Animal{...}
This method is not used by all those classes, but in the future it probably will.
The structure of one of my classes is:
public class Dog extends Animal {...}
The cleanest way is using abstract method but it obliges me to change all existing classes.
The workaround is to create "empty" method in abstract class:
public String getString(Map<String, Object> params){
return "";
}
and then override it when I need in classes that extend abstract class.
Is there any better solution?
Having an "empty" method is fine. But in order to be sure, that it will be implemented where it is really needed, consider throwing an exception by default from this method:
throw new UnsupportedOperationException();
A similar approach is used in java.util.AbstractList class:
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
I can't help feeling like you have some architectural/design issues here, but without knowing more, I can't say for sure. If 50 classes are going to inherit from Animal, but not all of them are going to use this method, then I'm wondering if they should really inherit from one common class. Perhaps you need further levels of sub-classing... think Kingdom->Phylum->Sub-Phylum. But my gut says that's still not the right answer for you.
Step back - what are you trying to accomplish? If you're going to implement this function on these classes in the future, then you must also be changing your code to know to use/expect this. The point of inheritance is to allow code to refer to an object's expected common behavior without knowing what type of object it's referencing. In your getString() example, you might have a function as such:
public string SendMessage(Animal someAnimal) {
string message = someAnimal.getString();
// Send the message
}
You can pass it a dog, a cat, a platypus - whatever. The function doesn't care, because it can query the message from its base class.
So when you say you'll have animals that don't implement this message... that implies you'll have logic that ensures only cats and dogs will call this function, and that a platypus is handled differently (or not at all). That kind of defeats the point of inheritance.
A more modern approach would be to use interfaces to establish a "has a" relationship instead of an "is a" relationship. A plane might have an IEngine member, but the specific type of engine can be set at run-time, either by the plane class itself, or by the app if the member is writeable.
public interface IEngine {
string getStatus();
string getMileage();
}
public class Cessna {
public IEngine _engine;
public Cessna() {
_engine = new PropellerEngine();
}
}
You could also inherit directly from that interface... Animals that don't implement IAnimalMessage wouldn't implement that function. Animals that do would be required to. The downside is that each animal will have to have its own implementation, but since your base class currently has an abstract function with no body, I'm assuming that's a non-issue. With this approach, you can determine if the object implements the interface as such:
IAnimalMessage animalMessage = myPlatypus as IAnimalMessage;
// If your playtpus doesn't implement IAnimalMessage,
// animalMessage will be null.
if (null != animalMessage) {
string message = animalMessage.getString();
}
public interface IAnimalMessage {
string getMessage();
}
public class Platypus : IAnimalMessage {
// Add this implementation when Platypus implements IAnimalMessage...
// Not needed before then
public string getMessage() {
return "I'm a cowboy, howdy, howdy, howdy!";
}
}
That's probably the closest to what you're asking for I can suggest... classes that don't need the message won't implement that interface until they do, but the code can easily check if the interface is implemented and act accordingly.
I can offer more helpful/specific thoughts, but I'd need to understand the problem you're trying to solve better.

composition-and-forwarding approach for a class with two Lists

I have read Item 16 from Effective Java and
Prefer composition over inheritance? and now try to apply it to the code written 1 year ago, when I have started getting to know Java.
I am trying to model an animal, which can have traits, i.e. Swimming, Carnivorous, etc. and get different type of food.
public class Animal {
private final List<Trait> traits = new ArrayList<Trait>();
private final List<Food> eatenFood = new ArrayList<Food>();
}
In Item 16 composition-and-forwarding reuseable approach is suggested:
public class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) {this.s = s;}
//implement all interface methods
public void clear() {s.clear();}
//and so on
}
public class InstrumentedSet<E> extends ForwardingSet<E> {
//counter for how many elements have been added since set was created
}
I can implement ForwardingList<E> but I am not sure on how I would apply it twice for Animal class. Now in Animal I have many methods like below for traits and also for eatenFood. This seems akward to me.
public boolean addTrait (Trait trait) {
return traits.add(trait);
}
public boolean removeTrait (Trait trait) {
return traits.remove(trait);
}
How would you redesign the Animal class?
Should I keep it as it is or try to apply ForwardingList?
There is no reason you'd want to specialize a List for this problem. You are already using Composition here, and it's pretty much what I would expect from the class.
Composition is basically creating a class which has one (or usually more) members. Forwarding is effectively having your methods simply make a call to one of the objects it holds, to handle it. This is exactly what you're already doing.
Anyhow, the methods you mention are exactly the sort of methods I would expect for a class that has-a Trait. I would expect similar addFood / removeFood sorts of methods for the food. If they're wrong, they're the exact sort of wrong that pretty much everyone does.
IIRC (my copy of Effective Java is at work): ForwardingSet's existence was simply because you cannot safely extend a class that wasn't explicitly designed to be extended. If self-usage patterns etc. aren't documented, you can't reasonably delegate calls to super methods because you don't know that addAll may or may not call add repeatedly for the default implemntation. You can, however, safely delegate calls because the object you are delegating to will never make a call the wrapper object. This absolutely doesn't apply here; you're already delegating calls to the list.

Casting to a bounded type

I have a class hierarchy where cousins share very similar functionality. For example:
Node
Statement
FunctionCallStatement
Expression
FunctionCallExpression
FunctionCallStatement and FunctionCallExpression share a very similar API, but I cannot express that in pure class terms with a single-inheritance hierarchy. So, I've created an IsFunctionCall Interface which both of these implement. I can now declare a method which takes either a FunctionCallStatement or a FunctionCallExpression as follows:
void <T extends Node & IsFunctionCall> doSomething(T node) { ... }
This all works very nicely.
Unfortunately, I've now found myself faced with a rather awkward problem. I have a Node; I know dynamically that it must be either a FunctionCallStatement or a FunctionCallExpression; I need to pass that Node into the doSomething() method above. I cannot find a way to upcast it to an appropriate type.
Right now I'm using a chain of instanceof to determine which class the Node is and to cast it to the appropriate concrete type, but that's butt-ugly. The only other way I know to make this work is to make an IsNode interface and have everything that currently expects a Node expect an IsNode instead; this would allow me to declare a union interface that implements IsNode and IsFunctionCall and let me do away without the generics above. But that's a hell of a lot of work and is still pretty ugly.
Is there an alternative way to do this?
(Note: example above is a simplified version of my actual code.)
Update: I tried the following piece of evil:
#SuppressWarnings("unchecked")
private <S extends Node & IsFunctionCall> S castNode(Node node)
{
return (S) node;
}
and then:
doSomething(castNode(node));
I got some very strange error messages. It would appear that the type inference used to determine the S of castNode() will not match against the T in the declaration of doSomething(); it's using the concrete type only and setting S to Node. Which of course does not match doSomething()'s declared type. Very peculiar.
Update update:
This appears to be a close duplicate of How should I cast for Java generic with multiple bounds?. My situation is slightly different because my bounds include an object and an interface, while the one in the other question has two interfaces, but it's still applicable.
Looks like I need to go and reengineer my entire application. Sigh.
Any admin, feel free to close this as a duplicate...
I think the way out of this, although not exactly elegant, is to have a few overloads for doSomething:
void doSomething(FunctionCallStatement node) ...
void doSomething(FunctionCallExpression node) ...
You are using the interface to flag functionality, how about passing as argument a reference to the FunctionCallInterface which offers access to the function call abstraction?
doSomething won't have to know the actual implementation type as long as it can access the relevant information and call relevant methods on the implementation objects.
public class FunctionCallStatement extends Statement implements FunctionCallInterface {
}
void doSomething(FunctionCallInterface node) {
}

Categories