super of sub function - java

I have a function in my superclass (Speler) that is called kiesKaart:
public Kaart kiesKaart(int spelerIndex){...}
In my subclass function, I have the same function with an other parameter that overrides (i do have #Override before it, changing this to #Override() does not help...) the super function:
public int kiesKaart(Kaart lak){...}
In my main I have an array of Spelers, where only the first is an Speler and the others are AiSpelers (this is the name of the subclass):
spelerArr[0] = new Speler(hand[0]);
for (int i=1;i<AANTALSPELERS;i++) {
spelerArr[i] = new AiSpeler(hand[i]);
}
Later on in my code I address spelerArr[i].kiesKaart, so now I want the code to address the correct instance of kiesKaart.
How can I do this?

The signatures do not match. So you are not overriding the method in super class. The compiler will complain if you use #Override. The signature of the method also includes the type of the parameter.

You overloaded the method by creating a new one with the same name and different arguments. Override is a different thing.

Using #Override will do nothing here because the two methods are different. The first one returns type Kaart given an int, and the second returns type int given a Kaart.
In other words, to make sure you are calling the right method, you need to make sure you send the right parameter (int for the first, Kaart for the second).

I believe you are going to have to use instanceof to determine if it is a Speler or AiSpeler and cast it to the appropriate object before calling kiesKaart.

You are overloading your superclass method, not overriding. Having an annotation does not change this fact.
If you want to determine the type of the calling object (polymorphism) you have to override the method - same parameter list, same return type or a subclass (as of Java 5) and of course the same name.

This might be helpful as a quick reference on what is possible and what not, and how to call it

Related

Pass an instance of the subclass to a method and use it later within that method

I have a method (prepareErrorMessage) that accepts objects of type ErrorMessagePojoSuperclass. However, I only pass subclasses of ErrorMessagePojoSuperclass as arguments:
public class ErrorMessagePojoBundle extends ErrorMessagePojoSuperclass {}
public class Tester {
ErrorMessagePojoBundle empb = new ErrorMessagePojoBundle();
prepareErrorMessage(empb);
public void prepareErrorMessage(ErrorMessagePojoSuperclass errorMessagePojo) {
String errorStatusMsg = messageConverter.convertXMLToString(errorMessagePojo);
}
}
The class ErrorMessagePojoBundle has more methods than its superclass.
I need to make sure that when the line of code is running messageConverter.convertXMLToString(errorMessagePojo), messageConverter processes an instance of the subclass - in this case the object empb. Any ideas? I want to solve this without the use of casting. Thank you.
Any ideas? I want to solve this without the use of casting.
Your options are:
Defining an interface with the necessary method, having the subclass implement it, and using that interface as the parameter type rather than the superclass.
Changing the parameter type to the subclass, not the superclass.
instanceof and casting (not usually what you want to do).
1 and 2 are basically just variants of each other.
In your example code, there's no reason for prepareErrorMessage to accept the superclass rather than the subclass (or an interface), since the only thing it does can only be done with the subclass (or something implementing the same interface).

Confusing polymorphism in Java

Consider this code (complete class, runs fine, all classes in one class for the sake of brevity).
My questions are after the code listing:
import java.util.LinkedList;
import java.util.List;
class Gadget {
public void switchon() {
System.out.println("Gadget is Switching on!");
}
}
interface switchonable {
void switchon();
}
class Smartphone extends Gadget implements switchonable {
#Override
public void switchon() {
System.out.println("Smartphone is switching on!");
}
}
class DemoPersonnel {
public void demo(Gadget g) {
System.out.println("Demoing a gadget");
}
public void demo(Smartphone s) {
System.out.println("Demoing a smartphone");
}
}
public class DT {
/**
* #param args
*/
public static void main(String[] args) {
List<Gadget> l = new LinkedList<Gadget>();
l.add(new Gadget());
l.add(new Smartphone());
for (Gadget gadget : l) {
gadget.switchon();
}
DemoPersonnel p = new DemoPersonnel();
for (Gadget gadget : l) {
p.demo(gadget);
}
}
}
Questions:
From the compilers point of view, what is the origin of the switchon method in Smartphone? Is it inherited from the base class Gadget? Or is it an implementation of the switchon method mandated by the switchonable interface? Does the annotation make any difference here?
In the main method, first loop: Here, we see a case of runtime polymorphism - i.e., when the first for loop is running, and gadget.switchon() is called, it first prints "Gadget is switching on", and then it prints "Smartphone is switching on". But in the second loop, this runtime resolution does not happen, and the output for both calls to demo is "Demoing a gadget", whereas I was expecting it to print "Demoing a gadget" the first iteration, and "Demoing a smartphone" the second time.
What am I understanding wrong? Why does the runtime resolve the child class in the first for loop, but doesn't do so in the second for loop?
Lastly, a link to a lucid tutorial on runtime/compile-time polymorphism in Java will be appreciated. (Please do not post the Java tutorial trail links, I didn't find the material particularly impressive when discussing the finer nuances in respectable depth).
This is how it works shortly:
Compiling time
The compiler defines the required signature for the requested method
Once the signature is defined, the compiler starts to look for it in the type-Class
If it finds any compatible candidate method with the required signature proceeds, otherwise returns an error
Runtime
During execution JVM starts to look for the candidate method with the signature as exactly defined during the compiling-time.
The search for the executable method actually starts from the real Object implementation Class (which can be a subclass of the type-Class) and surf the whole hierarchy up.
Your List is defined with type Gadget.
for (Gadget gadget : l) {
gadget.switchon();
}
When you ask for gadget.switchon(); the compiler will look for the switchon() method in the Gadget class and as it's there the candidate signature is simply confirmed to be switchon().
During the execution, the JVM will look for a switchon() method from the Smartphone Class and this is why it is displaying the correct message.
Here is what happens in the second for-loop
DemoPersonnel p = new DemoPersonnel();
for (Gadget gadget : l) {
p.demo(gadget);
}
The signature in this case is for both objects demo(Gadget g), this is why for both iterations method demo(Gadget g) is executed.
Hope it helps!
From the compilers point of view, what is the origin of the switchon method in Smartphone? Is it inherited from the base class Gadget? Or is it an implementation of the switchon method mandated by the switchonable interface?
The second case
Does the annotation make any difference here?
Not at all, #Override is just a helper, whe you use it you are telling the compiler: "my intention is to override the method from a supertype, please throw an exception and don't compile this if it is not overriding anything"
About the second question, in this case the method that better match acording to its signature is the one to be called. At run time in the second loop your objects have the supertype "associated", that's the reason public void demo(Gadget g) will be called rather than public void demo(Smartphone g)
1.It shouldn't matter. Because it is extending Gadget, if you don't override and call switchon() from a smartphone, it would say "Gadget is switching on!". When you have both an interface and a parent class with the same method, it really doesn't matter.
2.The first loop works and the second doesn't because of the way java looks at objects. When you call a method from an object, it takes the method directly from that object, and thus knows whether smartphone or gadget. When you send either a Smartphone or Gadget into an overloaded method, everything in that class is called a Gadget, whether it is actually a smartphone or not. Because of this, it uses the gadget method. To make this work, you would want to use this in the demo(Gadget g) method of DemoPersonnel:
if(gadget instanceof Smartphone){
System.out.println("Demoing a gadget");
}else{
System.out.println("Demoing a smartphone");
}
Sorry I don't have a link to a tutorial, I learned through a combination of AP Computer Science and experience.
Answering question 2 first: In the second loop your passing an object typed as a Gadget therefore the best match in the demo class is the method taking a gadget. this is resolved a compile time.
for question 1: the annotation does not make a difference. it just indicates that you overriding (implementing) method in the interface.
For compiler, Smartphone inherits switchon() method "implementation" from Gadget and then Smartphone overrides inherited implementation with its own implementation. On the other hand switchonable interface dictates Smartphone to provide an implementation of switchon() method definition and which was fulfilled by the implementation overridden in Smartphone.
First case is working as you expected because it is indeed a case of polymorphism i.e. you have one contract and two implementations - one in Gadget and another in Smartphone; where later has "overridden" the former implementation. Second case "should not" work as you expect it to, because there's only one contract and one implementation. Do note that you are "not overriding" the demo() method, you are actually "overloading" the demo() method. And, overloading means two "different" unique method definitions that only shares the "same name". So, it is a case of one contract and one implementation, when you call demo() with Gadget parameter, because compiler will match the method name with exact method parameter type(s) and by doing so will call "different methods" in both iterations of the loop.
about the second question :
In Java, dynamic method dispatch happens only for the object the method is called on, not for the parameter types of overloaded methods.
Here is a link to the java language specification.
As it says :
When a method is invoked (§15.12), the number of actual arguments (and
any explicit type arguments) and the compile-time types of the
arguments are used, at compile time, to determine the signature of the
method that will be invoked (§15.12.2). If the method that is to be
invoked is an instance method, the actual method to be invoked will be
determined at run time, using dynamic method lookup (§15.12.4).
so basically :the compile time type of the method parameters is used to determine the signature of the method to be called
At runtime, the class of the object the method is called on determines which implementation of that method is called, taking into account that it may be an instance of a subclass of the declared type that overrides the method.
In your case when you create object of a child class by new child(); and pass it on to the overloaded method, it has superclass type associated. Hence overloaded method with parent's object is called.
The annotation does not make any difference here. Techinically is like you are doing both things: overriding parent switchon() and implementing the switchon() interface method in one shot.
Method lookup (with respect to method arguments) is not done dynamically (at runtime) but statically at compile-time. Looks strange but thats how it works.
Hope this helps.
The compiler selects a method signature based on the declared type of the "this" pointer for the method and the declared type of the parameters. So since switchon receives a "this" pointer of Gadget, that is the version of the method that the compiler will reference in its generated code. Of course, runtime polymorphism can change that.
But runtime polymorphism only applies to the method's "this" pointer, not the parms, so the compiler's choice of method signature will "rule" in the second case.

java explicitly call super method

Are there any reason to call method from super class?
I have met lots of places where super method called instead of this method, e.g.:
public String getCustomValue() {
String value = (String) super.getValue(someArgHere);
return value;
}
Any benefits? I just see one major problem with inheritance: if I override getValue in this class or in one of its descendants getCustomValue will neglect that override and call super method.
super.getValue(someArgHere) calls the getValue method of the super class. In contrast, this.getValue(someArgHere) calls the getValue method of the current class, if defined. If the current class does not override getValue, the super class method is called.
Unless you overwrote the method getValue(...) and you are really sure (your sureness deserves a comment in the code) you want to bypass it you should not use super like you are doing. Later on if you or someone else decide to overwrite getValue(...) they probably wanted the effect to apply to getCustomValue() as well.
Although you definitely can call super.myMethodOne() from myMethodTwo(), the usual scenario is when you want to call super.myMethodOne() from myMethodOne() when you override it. Some languages like Ruby even pass up the method arguments automatically for you so that you don't have to retype them.
Here is one example:
public class A {
public void close() {
// do a bunch of things...
}
}
public class B extends A {
#Override
public void close() {
// close things related to the subclass B
// and then make sure A is closed as usual...
super.close();
}
}
There are no technical advantages of using super over this in the case where the method is not overridden.
However, one might say that it's clearer to use super instead of this for the reason you've just mentioned. If you override the function in your subclass, then you will need to use super; if you don't you can use this. Instead of playing guessing games (or forcing people to check whether the method has been overridden), you can just always use super when you mean super.
I just see one major problem with inheritance: if I override getValue in this class or in one of its descendants getCustomValue will neglect that override and call super method.
Then don't call the super method explicitly, just call getValue. If the method has not been overriden it will default to the super-method. If it has, it will use the overriden method.
I don't know if it's appropriate to ask about "benefits" in this case - it really just depends on what exactly you are trying to accomplish.
The thing is the design. When we code, we do it as per what it is!
So even if getValue is extended, its perfect, because that is what your class is suppose to do.
Normally, super is used, to obtain any information or data or side effect from the super type and modify or improve it as per your current class functionality
The only benefit is if your class overrides the method of the superclass you still can call the method of the superclass using super.

is it possible to get the class of the interface <Set>

Am having some arguments say (String a, Treeset b, Set c)
and I try to get the class by arguments[i].getClass(); of the above arguments..
is Iit possible to get the class of the interface <Set>.
For example:
Class[] argumentTypes = new Class [arguments.length];
for (int i = 0 ; i < arguments.length ; i++)
{
argumentTypes[i] = arguments[i].getClass();
}
The code you've given will find the classes of the arguments (i.e. the values provided to the method) - but those can never be interfaces; they'll always be concrete implementations. (You can never pass "just a set" - always a reference to an object which is an instance of an implementation of the interface, or a null reference.)
It sounds like you want the types of the parameters - which you'd get via reflection if you absolutely had to, finding the Method and then getting the parameters from that with getParameterTypes. But given that you're within the method, you already know the parameter types, because they're at the top of the method... I'm not sure the best way of finding "the currently executing" method, if that's what you're after.
If you're just trying to get the class associated with Set, you can use Set.class of course. But again, it's not really clear what you're trying to do.
EDIT: Okay, judging from your comment, there are some logical problems with what you're trying to do. Going from the values of arguments to which method would be invoked is impossible in the general case, because you've lost information. Consider this, for example:
void foo(String x) {}
void foo(Object y) {}
foo("hello"); // Calls first method
foo((Object) "hello"); // Calls second method
Here the argument values are the same - but the expressions have a different type.
You can find all methods which would be valid for the argument values - modulo generic information lost by type erasure - using Class.isAssignableFrom. Does that help you enough?
Note that you'll also need to think carefully about how you handle null argument values, which would obviously be valid for any reference type parameter...
You can use http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getInterfaces()
You will get the class what the caller provided.
I mean,in below class you will get HashSet.
Set set=new HashSet();
System.out.println(set.getClass());
You can do this in two ways given below
Set s = new //any class that implements it for example HashSet or TreeSet etc.;
s.getClass().getName(); //This will return the name of the subclass which is refered by s.
or if in other way can do it
Set s = null;
s.getClass();//This causes NullPointer Exception

Does a constructor have to use all parameters that are passed to it?

Does a constructor have to use all parameters that are passed to it?
For example: if there are three parameters passed to construct a new object, must all of the parameters be assigned?
Thanks in advance!
Technically no - you do not have to assign all parameters that are passed.
But the more important question is - why pass them on the first place if they are unused?
UPDATE
Let's assume you have this class:-
public final class SomeClazz {
private final int foo;
public SomeClazz(int foo,int bar){
this.foo = foo;
}
}
And you are invoking it this way:-
SomeClazz clazz = new SomeClazz(2,4);
There is no technical problem with this but as I mentioned above it does not make sense to have a constructor that takes 2 parameters but does not use it. In that case, you should create a constructor that takes just one parameter. Otherwise you are misleading the calling application into thinking that both arguments are being used to create the object.
In general, no. But if you're accepting a parameter and not doing anything with it, why is it there? For example:
class Foo {
public Foo(int w, int h) {
width = w;
height = 10;
}
private int width;
private int height;
}
In the constructor, h is not used. It could be removed from the constructor parameter list.
A constructor, just like any method in Java, does not have to use all its parameters. The call to the constructor, though, needs to supply values for all declared parameters.
A constructor is not required to use all parameters. Not using all parameters raises the interesting question of why they're all not used. This answer assumes you mean that you don't use all of the passed in parameters.
The short answer is no. A constructor, like any method does not have to use everything that is passed to it. However the purpose of a constructor is to "set up" your object, so not using a parameter seems pointless. If you are worried about potentially using a parameter sometimes, overload the constructor.
Of course. In Java, a constructor is a method call, after all; all parameters must have a value.
That will depend of the design of the classes, here is a list of possible repercussions:
1) the constructor will crash and throw and exception
2) the constructor wont crash but when you call a method of the class.
3) the constructor wont crash but you might not be able to assign a value to a property since it is marked as read only.
if you are the owner of the class my advice is too user overloaded constructors.
http://en.wikipedia.org/wiki/Function_overloading

Categories