views:

625

answers:

5

I have the following classes:

class foo {
    public void a() {
        print("a");
    }
    public void b() {
        a();
    }
}

class bar extends foo {
    public void a() {
        print("overwritten a");
    }
}

When I now call bar.b() I want it call the overwritten method a() in foo. It does, however, print "a".

+3  A: 

When I run the following:

public class Program {
    public static void main(String[] args) {
     bar b = new bar();
     b.b();
    }
}

class foo {
    public void a() {
       System.out.printf("a");
    }
    public void b() {
        a();
    }
}

class bar extends foo {
    public void a() {
        System.out.printf("overwritten a");
    }
}

I get the following output:

overwritten a

which is what I would expect to see.

Andrew Hare
You beat me by one minute. I get the same output.
Eddie
May be he beat you in posting, otherwise, I believe, we got this output way before this question is posted.
Adeel Ansari
+1  A: 

Are the methods defined as static? That's the only way I could see getting that result. I found a good explanation about that here: http://faq.javaranch.com/view?OverridingVsHiding

slau
+4  A: 

It may be that you are trying to use static methods, which won't work as they don't get overridden.

A good way of checking is to add the @Override annotation to bar.a() and see if the compiler gives you an error that a() isn't actually overidding anything

CurtainDog
+1 for the @Override recommendation
Rob
A: 

You may be confused if you are coming from C# or some other language where you have to explicitly declare virtual functions and/or overriding functions.

In Java, all instance functions are virtual, and can be overridden -- unless they are declared as private and/or final.

It is not necessary to specify the new @Override annotation to do so, adding the annotation just specifies that your intent is to override, and will cause a either a warning or error if it isn't an override. (If you accidentally misspelled the method name for example).

Andrew's example shows how this should work.

kenj0418
+1  A: 

Are your two classes in different packages? And is your foo class methods declared public, protected, or private or package local? Obviously if they are private, this won't work. Perhaps less obvious, is if they are package local (i.e. no public/protected/private scope) then you can only override them if you are in the same package as the original class.

For example:

package original;
public class Foo {
  void a() { System.out.println("A"); }
  public void b() { a(); }
}

package another;
public class Bar extends original.Foo {
  void a() { System.out.println("Overwritten A"); }
}

package another;
public class Program {
  public static void main(String[] args) {
    Bar bar = new Bar();
    bar.b();
  }
}

In this case, you will still get 'A'. If you declare the original a() method in Foo public or protected, you will get the result you expected.

Mike