Wednesday, May 27, 2009

Puzzle 28 - Change the Rules (Polymorphism)

Language – Java | Type – Concept | Last date 31-May-2009 12:00 p.m. IST | Points 3

Yesterday I was reading some of the old post here and some of them are pretty interesting. Sure a lot of them are simple run of the mill questions – but some are pure gems. This one is a favorite of mine. The answer is already there but it still would be good to hear your solutions for it.

So much for old nostalgia. Time to move on.

public class Base{
public void fooBar()

{System.out.println(
"Base Ahoy!");}
}

public class Derived

extends Base{
public void fooBar()

{System.out.println(
"Derived Ahoy!");}

public static

void main(String args[]){
Base b
= new Derived

();
b.fooBar();
//Get this should pint Base Ahoy!
}
}

Java dictates that polymorphism come into play when the Base class reference points to the derived class Object. Lets change that shall we?

Get this code to compile and run. Only instead of printing Derived Ahoy get the code to print Base Ahoy. Oh no If’s please!
Usual rules - Add any amount of code you like but no deletes.Make it tough?

Site of the day - http://www.javaonthebrain.com - Lots of cool applets out there -- Nostagia again!!!

Got an answer? Why don’t you leave it here.

14 comments:

  1. Base is not abstract so you can do a
    b = new Base();
    before the print...
    I'll see if I can get something better in awhile

    ReplyDelete
  2. the simplest approach would be to change the signature of the fooBar method in class Derived.
    that way when calling the method, the signature would not match with it's own, and the super's method would be executed.

    Unfortunately, since the "make it tough" prevents us from changing the signature of the methods, we can not go that way.
    Something that would work, however, is to re-instanciate object b:

    public static void main(String args[]){
    Base b = new Derived();
    b = new Base();
    b.fooBar(); //Get this should pint Base Ahoy!
    }

    I know this was kind of an easy way out. I promise i'll try to come up with a better solution later. Something that does not violate the initialization of object b :)

    ReplyDelete
  3. class Base{
    public void fooBar(){System.out.println("Base Ahoy!");}
    }

    public class Derived extends Base{

    public void fooBar(){
    super.fooBar();
    System.exit(0);
    System.out.println("Derived Ahoy!");}

    public static void main(String args[]){
    Base b = new Derived();
    b.fooBar(); //Get this should pint Base Ahoy!

    }
    }

    ReplyDelete
  4. Ok now that i dedicated more than 5 minutes to this one, there's another way of doing it, without messing with the main() block of the extending class.

    we simply make it so that the fooBar() method calls the super.fooBar(), and we interrupt the method itself with a System.exit() afterwards so that it doesn't print it's own message :)

    it's a sly approach, as it will exit the program, and if there was any other instruction after the b.fooBar(), it would not be executed. but it fits the rules (no overloading, no change of signature, no ifs, no deleted code)

    public class Derived extends Base{

    public void fooBar(){
    super.fooBar();
    System.exit(1);
    System.out.println("Derived Ahoy!");
    }

    public static void main(String args[]){
    Base b = new Derived();
    b.fooBar(); //Get this should pint Base Ahoy!
    }
    }

    ReplyDelete
  5. Please let me know whether this is correct answer.

    Line 6 changed to
    6 public void fooBar(){super.fooBar();System.out.println("Derived Ahoy!");}

    ReplyDelete
  6. Probably not the state of the art solution, but it work:
    public class Base{
    public void fooBar(){System.out.println("Base Ahoy!");}
    {}

    public static class Derived extends Base{
    public void fooBar(){System.out.println("Derived Ahoy!");}
    }
    public static void main(String args[]){
    Base b = new Derived();
    b = new Base();
    b.fooBar();
    }
    }

    ReplyDelete
  7. public static void main(String args[]){
    Base b = new Derived();
    b = new Base();
    b.fooBar(); //Get this should pint Base Ahoy!
    }

    ReplyDelete
  8. 1. Change name or signature of overloaded fooBar()
    2. "Derived Ahoy!".replace("Derived","Base") :)

    PS fix comment: maybe not *pint* but *print*?

    ReplyDelete
  9. Add 'static' to both fooBar methods.

    ReplyDelete
  10. public class Base {
    public void fooBar() {System.out.println("Base Ahoy!");}
    }

    public class Derived extends Base {
    public void fooBar() {System.out.println("Derived Ahoy!");}

    public static void main(String args[]) {
    Base b = new Derived();
    b = new Base();
    b.fooBar(); //Get this should pint Base Ahoy!
    }
    }

    ReplyDelete
  11. isnt it as simple as adding a new line of code after line 9 and re-allocating 'b' to a new object of Base class

    b = new Base ();

    ReplyDelete
  12. class Base{
    public void fooBar(){System.out.println("Base Ahoy!");}
    }

    public class Derived extends Base{
    public void fooBar(){System.out.println("Derived Ahoy!");}

    public static void main(String args[]){
    Base b = new Derived();
    b = new Base();
    b.fooBar(); //Get this should pint Base Ahoy!
    }
    }

    ReplyDelete
  13. class Base{
    public void fooBar(){System.out.println("Base Ahoy!");}
    }

    public class Derived extends Base{
    public void fooBar(){System.out.println("Derived Ahoy!");}

    public static void main(String args[]){
    Base b = new Derived();
    b = new Base();
    b.fooBar(); //Get this should pint Base Ahoy!
    }
    }

    ReplyDelete
  14. make the fooBar method static in both classes

    ReplyDelete

Solution for this question?