Java method override/interface problem - java

I have
interface FooI
class FooA implements FooI
class FooB implements FooI
class FooC implements FooI
I wrote a class "Handler" that has the following methods
static double handle(FooA f)
static double handle(FooB f)
static double handle(FooI f)
and I have a function like the following:
void caller(FooI f)
{
Handler.handle(f);
}
with f just being known as a class implementing FooI. However f is an instance of FooA
Instead of calling the method for FooA, the method for FooI is called.
When I use f.getClass().getName() I get the correct class name (FooA).
I am confused because I expected the best-suited method to get called, namely the one for FooA.
I wanted to use the FooI method as a fallback to handle classes that could be implemented later, and I also want to handle f without having one big function where I am doing instanceof checks for all currently known classes implementing my interface.
What would be a good approach to do this?

Overload resolution is done at compile time rather than execution time in Java. The signature was picked based on the compile-time type of your variable. Only overrides are determined at execution time.
A common solution for this in languages like Java is to use double dispatch and the visitor pattern.
Personally I'm not a huge fan of this. I prefer to try to design my way around it. That's not always possible, of course, but it's worth at least attempting.

You expect that the JVM seaches for the best fitting method at run time but that doesn't happen, actually. Instead the method to call is selected during compile time, when the only known information is that f is a class that implements FooI.
The best approach for that problem, the one that avoids the instanceof checks, might be moving the "handle" method into those classes FooA, FooB, FooI.

I don't know exactly what your design is, but might the 'handle' functionality be better placed in your concrete FooI implementations?

Java resolves which method to call at compile time using the reference type, which in your example is FooI - if you think about it this makes sense as the reference type is all it really has to go on at compile time.
Your Handler class doesn't handle(FooI f) and so as far as the compiler is concerned there is no valid handle method to call.

you should not use a static method for that, static methods obey to other rules than non final instance methods

You could transform your interface into an abstract class, with a handler implementation. Then you implement it, and FooA and FooB overrides it

Related

Confusion on Polymorphism java

I was reading up on Polymorphism and after some searching I was confused about about the difference of compile-time and run-time polymorphism.
Lets say i have a class ABC and one other class that extends ABC,
class DEF like so:
class ABC{
public void myMethod(){
System.out.println("Overridden Method");
}
}
public class DEF extends ABC{
public void myMethod(){
System.out.println("Overriding Method");
}
}
public static void main(String args[]){
ABC obj = new DEF();
obj.myMethod();
}
}
If we want to be able to replace a class with another class, which performs the same task but in a different way without having too recompile the class that calls them, Is method overriding the way or method overloading?
I guess you are asking two things
1) I was reading up on Polymorphism and after some searching I was
confused about about the difference of compile-time and run-time
polymorphism.
Let's separate the waters here a little bit...
At compile time the compilator validates and transform the code into bytecodes. The static methods calls are resolved during this phase so you know every time the static method is invoked the same and sole implementation will take place.
run-time polymorphism is what happen at execution to decide what actual implementation of a given method to chosse. Considering that each class in the hierchary provides one implementation of this "polymorphic" method. Behind the curtains the compiler do a lot of work to archieve this, using something known as late binding mechanism.
2) If we want to be able to replace a class with another class, which
performs the same task but in a different way without having to
recompile the class that calls them, Is method overriding the way or
method overloading?
You don't actually say that replaces, inteads talks about extends, that is the thing that your are doing when a class extends another. And the implementations of the a method in parent class can be overwritten in a subclass.
Overload, has nothing to do with hierarchies, is to write the same method with diferents set of parameters.
Overloading is when you create multiple classes with the same method name, but different params. If a subclass has the exact same method name and params, it really ends up being overwriting, whether your put #overwrite on top or not. It´s literally the same exact thing and either way you change the outcome of the method, even if you use the base/super - class as a type.
This could be helpful When do you use Java's #Override annotation and why?
You´ll make your compiler complain that you are not actually overwriting a function if you mistype one of the two and nothing ends up being overwritten and you´ll make your code easier to read. It won´t affect the outcome, but you still should use it for those reasons.

Interface referencing an inner class of its implementation

I am refactoring a piece of code and I have to made a method (lets call it myMethod) in one class (let's call it TestImpl) from private to public. Therefore, I try to add this method to its interface (ITest).
However, the problem is that a parameter of the method references to an inner class of TestImpl. i.e. something like:
myMethod (TestImpl.NewType var1, ...)
This seems a bit weird to me as the interface references to its own implementation. What is the best solution here? Or, is it really a problem?
As I understand it's static class, then it shouldn't be a problem. However, I think it's better to move that NewType out of TestImpl or even create new interface to generalize this NewType
It violates the DI principles, Interface should not have nay compile dependencies to its implementations. NewType should be extracted as a interface or class to outside.

Forcing subclasses to have a particular factory method or constructor

I am 70% confident that this is impossible, but is there a way to make sure that subclasses have a particular constructor or factory method?
In this case, I am trying to create a StringSerializable that would require subclasses to have the following methods
toString, which converts the object to a String.
fromString, which gets an instance from a String.
Obviously, in the first case, I can just make toString abstract. On the other hand, having a nonstatic fromString seems to be problematic. However, I can't create an abstract static method. I also do not think that a constructor is entirely appropriate.
You're correct; it's impossible to force it at compile time. There are various tricks you could do at runtime (such as using reflection in tests), but that's about it.
But ask yourself: why do you want to require that? You can't dynamically invoke a static method or constructor (except through reflection), so how exactly would you use those required factories, if you had them?
If it's just for consistency in the code (which is a good thing!), then you'll just have to ensure that consistency as you develop the code base. A comment in the base class can go a long way here, as can code reviews and other "soft" techniques.
If you plan to use the factories in reflection, then similar reflection can be used in tests to make sure that each subclass has the bits it needs.
Another option is to create a non-static factory:
public interface FooMaker() {
Foo create(String arg);
}
... and use that, rather than a static fromString method.
There again you have the same problem of "how do I ensure that every subclass has a FooMaker implementation?" and again I would say that you shouldn't worry about that. If you make the FooMaker the "starting point" of your code, rather than the subclasses, then it doesn't matter what the subclasses are doing; all that matters is that your FooMakers give you a way of going from string to Foos, and each Foo has a way of going back to a string.
the following code does ensure that every subclass needs to implement the static method, if the subclass does not implement the method it will fail when classes are constructed, as close as you can get to a compile time error, but not at compile time
the exception thrown is very clear and the programm will instantly fail when started
public abstract class Base {
static Functional test;
static {
if(test == null) {
throw new RuntimeException("You need to provide an implementation for the implemntMe method in class base");
}
}
private interface Functional {
Base implementMe(int whatever, boolean anotherParameter);
}
public static void main(final String[] args) {
}
}
the private interface construct ensures that only lambdas can be used to implement the method
a subclass would have to look like this
public SubClass extends Base {
static {
test = (int whatever, boolean anotherParameter) -> {
Subclass tmp = new Subclass();
//construct object
tmp.setWhatever(whatever);
return tmp;
}
}
}
lamdas are like inline methods that implement a functional interface, an interface which has only one abstract method
you can also declare the interface publicly at any other place and implement it with an anonymous inner class,
but my way makes sure that programers have to copy and paste code to reuse it,
or need to copy the object of Functional from another class

What is the compile time type of this? (in Java)

I suspect it is the type of the class in which it is written but I am not 100% sure, could someone please confirm my suspicion and perhaps give a reference to Java Language Specification where this behaviour is defined?
Let's say class A has a method a() which uses the this keyword in its body, and class B extends class A. Now class B has inherited method a(), however, I am not sure if the compile time type of this in B.a() is now A or B ?
I am asking this because I am trying to understand how the visitor pattern works, as it is described in this Robert C. Martin's Visitor chapter from The Principles, Patterns, and Practices of Agile Software Development.
It seems to be crucial to know the compile time type of this if one wants to fully understand the visitor pattern because overloaded method calls are resolved at compile time. More specifically, I refer to the compile time type of this in the accept methods in the visitor pattern.
The type of this is the type of the class in which it is used. In fact, it is crucial for the visitor pattern from the article to work.
Visitor pattern implements double dispatch in two steps - selecting the appropriate accept method in the object being visited (first leg), and then selecting the appropriate visit method in the visitor (second leg). The first leg is implemented through overriding; the second leg is implemented through overloading.
Note that it is not necessary to use overloading for the second leg. In fact, it is common not to use it there for better readability. Compare these two implementations:
// Copied from Listing 29-2
public interface ModemVisitorOverload
{
void visit(HayesModem modem);
void visit(ZoomModem modem);
void visit(ErnieModem modem);
}
public interface ModemVisitorNoOverload
{
void visitHayes(HayesModem modem);
void visitZoom(ZoomModem modem);
void visitErnie(ErnieModem modem);
}
The second implementation is not using the overloading. It works in exactly the same way, except human readers of the code immediately see what is going on.
this is a reference to the current object and as the JLS 15.8.3 states
The type of this is the class C within which the keyword this occurs.
At run time, the class of the actual object referred to may be the class C or any subclass of C.
Thank you for the answers.
After reading the answers I got inspired to try to compile the code below. The result of this little experiment might give also some insight into the answer to the original question.
The code below does not compile because this in A is not the correct type (according to the compiler). So for the visitor pattern to work the accept method needs to be repeated in subclasses of A and the methods called by v.visit(this) are fixed already at compile time (as others have pointed out already in their answers).
The point of the original question was whether one could avoid this redundancy in code but it seems not.
class A{
void a(VisitorI v){v.visit(this);}
}
class B1 extends A{}
class B2 extends A{}
interface VisitorI{
void visit(B1 b1);
void visit(B2 b2);
}
class Visitor implements VisitorI{
public void visit(B1 b1){
System.out.print("b1");
}
public void visit(B2 b2){
System.out.print("b2");
}
}
There's no such thing as B.a. There is only one method here and that is in class A, so this obviously has the static type of A. This isn't C++ where function bodies get duplicated willy nilly (if you use templates).
Now if you created a method named a inside of class B, then this would have the static type of B inside that method. And thanks to the magic of virtual methods, it would get called based on the runtime type when you invoke .a() on an object that could be either type A or B. But this is onyl if you override A's method.
An instance of an Object can only have one type. In the case of an instance of B extends A then this will always be a B, even inside methods of A.
However you can always use an object of type B as thought it is an an object of type A so even though getClass will return a B all the methods within A can use this as though it were a A.
For example its completely valid to do:
A a = new B(); // Valid as B extends A
a.test();
If B declares a method test() then that version of the method will be called, even though you are referring to it as though it were an A.
This is also how things like over-riding methods can be used to change the behavior of a base class from a sub class. When you have a method test() in A, and then override the method in B then whenever code in A calls this.test() it will actually call the over-ridden method in B.
Your mistake comes from the assumption that Overriding is resolved at compile time. It's not, it's resolved at run time Over load ed methods are resolved at compile time. Over ride n methods are resolved at run time. Overloading and Overriding are very different things.

Runtime polymorphism

Suppose I have class A
public class A
{
public void method()
{
//do stuff
}
}
Also another class B
public class B extends A
{
public void method()
{
//do other stuff
}
}
Now I have the following statements:
A a = new B();
a.method();
Is this an example of run time polymorphism? If yes, then is no binding is done for the reference a at compile time?
The compiler will tell you that this can't work, because there's no relationship between A and B that will allow you to write A a = new B();
B either has to extend A or both have to implement a common interface with void method() in it.
You could have answered this very quickly by trying it with the compiler. Be an experimentalist - it's faster than forums.
UPDATE:
It works, now that B extends A. The binding that you care about, dynamic binding, is done at runtime. The static compile time type for the variable "a" is class A; at runtime it is dynamically bound to a reference of type B. Yes, I would consider this to be an example of polymorphism.
I was waiting to put my answer to another post, into a more correctly classified problem. Your question fits the concept, I've tried to explain in detail. but, since I don't know how link answers, I'll just copy/paste the complete script here .... Kindly go through it, you'll understand everything that there is to understand about your problem, you've asked
let's say compiler has to resolve a call like this : *
A a = new AA(); // Assume AA to be some subclass of class A
a->someFunc(); // and we're invoking a method "someFunc()' on a
*.
Now, compiler will go over following steps methodically.
1.) Firstly, compiler knows the declared type of variable a, so it will check whether the declared type of object a (lets call this, class A for time being), have a method with the name someFunc() and that it must be public. This method could either be declared in class A, or it could be a derived method from one of the base class(es) of class A, but it doesn't matter to compiler and it just checks for it's existence with it's access specifier being public.
Needless to say any error in this step will invite a compiler error.
2.) Secondly, once the method is validated to be a part of the class A, compiler has to resolve the call to the correct method, since many methods could be there with same name (thanks to function overloading). This process of resolving correct method is called overloading resolution. Compiler achieves this by matching the signatures of the called method with all the overloaded methods that are part of the class. So, of all the someFunc() s only the correct someFunc() (matching the signatures with called method) will be found and considered further.
3.) Now comes the difficult part, It may very well happen that someFunc() may have been overridden in one of the subclasses of the class A (lets call this class AA and needless to say it is some subclass of A), and that variable a (declared to be of type A) may actually be referring to an object of class AA, (this is permissible in C++ to enable polymorphism). Now, if the someFunc() method is declared to be of type virtual, in base class (i.e. Class A) and someFunc() has been overriden by subclass(es) of A (either in AA or classes between A and AA), the correct version of someFunc() have to be found out by the compiler.
Now, imagine you're the compiler and you have this task of finding whether the class AA has this method. Obviously, class AA will have this method since, it is a subclass of A and public access of A in class A has already been validated in Step 1 by the compiler !!! . But Alternatively, as mentioned in previous paragraph, someFunc() may be overriden by class AA (or any other class between A and AA), which is what compiler needs to catch. Therefore, you (since, your'e playing the compiler) could do a systematic check to find the bottom-most (lowest in the inheritance tree) overridden method someFunc() starting from class A and ending at class AA. In this search, you'll look for same method signatures as was validated in overloading resolution. This method will be the method which will be invoked.
Now, you may be wondering, "What the heck", is this search done everytime ? ... Well, Not really. The compiler knows the overhead of finding this everytime, and as such, maintains a data-structure called Virtual Table for every class type. Think of virtual table, as mapping from method signatures (which are publicly accessible) to the function pointers. This virtual table is made by compiler during compilation process and is maintained in-memory during program execution. In our example, class A and class AA will both have their own virtual tables. And when compiler has to be find someFunc() in class AA (since actual object pointed by variable a is of type AA), it will simply find the function pointer through the virtual table of Class AA. This is as simple has hashing into the table and is a constant time operation.
Regards
AViD
The code example you've given isn't legal, so I guess the answer is that it's not a kind of polymorphism.
You can't assign a class to a variable of an unrelated type like that. I'm guessing that you might be intending for B to derive from A?
Is this an example of run time polymorphism?
As of the edit: yes that would be runtime polymorphism, since which method is actually executed depends on what is assigned to a.
Edit:
If method() would be static, then calling a.method() would always result in the version of A being called. However, you'd then just write A.method() and if you don't do that any decent IDE would warn you about that (because it might be misleading to call a static method on an instance).
End Edit.
Compile time polymorphism would be the overloading mechanism, i.e. the compiler decides whether to use someMethod(Number) or someMethod(Integer) depending on what it knows about the parameter that is passed (if you pass a Double or just a Number it would be the first one, if you pass an Integer it would be the second).
If yes, then is no binding is done for the reference a at compile time?
What do you mean exactly? Note that the type of a will be A so you can assign everything that extends A at runtime. The compiler will just complain if the assigned value is not an A (you might trick the compiler with a cast, but this is just evil and if this breaks your program, you have been warned ;) )
It should be
public class B extends A {
public void method()
{
//do other stuff
} }
If it were compiling, it would be the B::method() that would be called. (only if you changed your code to make the B class inherit the A class).
In this case your use your object like it was only an A, but if some methods are overidden in B, then these methods are called, instead of A's methods.

Categories

Resources