Reputation: 1462
public class monstertestdrive {
public static void main(String[] args) {
monster[] ma=new monster[3];
ma[0]=new vampier();
ma[1]=new monster();
ma[2]=new dragon();
for(int x=0;x<3;x++){
ma[x].frighten(x);
}
}
}
class monster{
boolean frighten(int d){
System.out.println("arrah");
return false;
}
}
class vampier extends monster{
boolean frighten(int x){
System.out.println("a bite?");
return true;
}
}
class dragon extends monster{
boolean frighten(int degree){
System.out.println("breath fire");
return true;
}
}
Is the return type mentioned in frighten method serves any purpose? I asked this because i interchanged the return types but the output was same. But when i changed the array object place i.e. 0,1 and 2 then i got a different output.
Upvotes: 1
Views: 311
Reputation: 692
The boolean return and the integer parameters have no affect on your output because the methods make no use of them. You never use the return values from any of the methods to set any variables or determine the output. You also never use any of the passed in values to change anything within the method or output from the method. You may want to read up more on return types and methods and parameters first; it's basic knowledge that unless you plan to use the parameters or a return value, there's no reason to have either. Once you understand that we can move on to why each element of the array outputs a different version of frighten.
You may want to read a bit first about concrete and abstract classes, polymorphism and inheritance.
What you're looking at is an instance of dynamic (or late) method binding.
Your parent CONCRETE class (monster) has a specific implementation of frighten():
boolean frighten(int d){
System.out.println("arrah");
return false;
}
This implementation of frighten has been written with a boolean return type and an integer parameter. When you extend this class, the child class inherits this method. Say I create another child class werewolf:
class werewolf extends monster{}
At first glance this class has no methods or attributes associated with it; but in reality, due to class inheritance it implicitly has the frighten method declared in its parent class. This is what the compiler sees:
class werewolf extends monster{
boolean frighten(int d){ // Method **from** the parent class
//This is implicitly built into the subclass due to inheritance
System.out.println("arrah");
return false;
}
}
However, these methods are not set in stone. Within the child class it is possible to override parent class methods. This is what you have done in your vampier and dragon subclasses. This is an override because your methods have the same return type, same method name, and same parameters. If you were to change any of these things it would be a different method altogether and would not be an override of the parent method; you should get into the habit of using the @Override directive which tells the compiler to check and make sure that you are actually following the right format for an override.
class dragon extends monster{
@Override // This tells the compiler to check the parent for this method you are going to override and if you've followed the right format
boolean frighten(int degree){
System.out.println("breath fire");
return true;
}
}
Dynamic/late method binding is the ability of a program to resolve references to their respective class implementations at runtime.
All your subclasses are instances of the superclass they extend, so when you create an array of references to the superclass type, you can populate them with subclasses (a bit of a self promo here: Why can an array of references to an interface house classes that implement that interface?).
This is because subclasses have an ISA relationship with their parent class. However when you execute your main method:
for(int x=0;x<3;x++){
ma[x].frighten(x);
}
You haven't explicitly told the compiler, how do I pick which version of frighten() to use? Well that's the great thing about polymorphism - You don't have to. When the code executes, it's smart enough to look at the actual class that the reference is pointing to and, if the method is overridden properly, say HEY, there's a different local implementation of this method, let's execute that one and not the one in it's parent class. However, if you change the return value or the parameters of the frighten() method in a child class in any way, it becomes not an override, and the executed method will default to the type of the reference (in this case the monster class because your reference array is one of monsters).
So this isn't an issue with how boolean works, but an issue of how to properly use overridden methods. Hope this helped you out!
Upvotes: 1
Reputation: 1053
I would bet on changing the return type in Monster's frighten method (ie. from boolean to int then then the return value from false to 0) to experiment different polymorphic situations... and then get a different output
Upvotes: 0
Reputation: 31194
Yes, the return types do matter. the boolean
return type returns either true
or false
. You can also make an int
return type and return a number. this is handy for many things
for example:
int sum(int x, int y)
{
return x + y;
}
You're not noticing a difference because you're not doing anything with the return value
ma[x].frighten(x);
If your function has nothing meaningful to return, than you might as well make the return type void
and return nothing at all
void frighten(int degree){
System.out.println("breath fire");
}
Upvotes: 0