1
 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.

Shantanu Nandan
  • 1,438
  • 8
  • 30
  • 56
  • 1
    Not clear what you're asking. The calls to `frighten` will each return a boolean result, but you aren't doing anything with that result anywhere, so it isn't surprising that changing that boolean result doesn't affect anything. What were you expecting? – Jacob Mattison Feb 21 '14 at 15:49
  • In addition, if you change the order of the array elements and then iterate over them _in order_, the output would naturally be different. – Thomas Feb 21 '14 at 15:51
  • @JacobM Actually this program was written in a book(Head First Java) and according to the book if we change the return type from true to false then we receive a different output. Because of this i got confused and asked this question on this forum. – Shantanu Nandan Feb 21 '14 at 15:52
  • Don't have a copy of Head First Java handy, but I'll bet anything you've changed something from what was in the book. Look at the line `ma[x].frighten(x);`. For the return value to have any effect, you'd have to do something like `bool result = ma[x].frighten(x);`, and then do something with `result`. – Jacob Mattison Feb 21 '14 at 15:54
  • @JacobM When i change the argument type in frighten method from int to byte then why the dragon frighten method is not printing and method in monster is printing twice – Shantanu Nandan Feb 21 '14 at 16:12
  • If you change the return value in one of the `frighten` methods then you have to change it for all of them, or else the version in the subclasses isn't overriding the version in the parent. – Jacob Mattison Feb 21 '14 at 16:21

3 Answers3

1

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!

Community
  • 1
  • 1
Terry Chern
  • 694
  • 1
  • 8
  • 15
0

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");
}
  • When i change the argument type in frighten method from int to byte then why the dragon frighten method is not printing and method in monster is printing twice – Shantanu Nandan Feb 21 '14 at 16:11
  • @Shantanu it's because both your classes inherit `frighten(int)` from monster, and when you make that change, dragon no longer has a `frighten(int)` to override it, so it uses the one it inherited from monster – Sam I am says Reinstate Monica Feb 21 '14 at 16:15
0

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

floppy12
  • 1,045
  • 6
  • 12
  • When i change the argument type in frighten method from int to byte then why the dragon frighten method is not printing and method in monster is printing twice – Shantanu Nandan Feb 21 '14 at 16:12
  • From which method are you changing the argument type ? frighten in Dragon ? – floppy12 Feb 21 '14 at 16:15
  • By changing the argument type to Byte in Dragon's frghten method, you are not overriding the method inherited from Monster anymore but now overloading with another signature. At runtime there is two methods to choose but only one matches the argument type : it's the Monster's one. So you see the corresponding output – floppy12 Feb 21 '14 at 16:26