Yes, that's right. It's possible to override a method that you didn't inherit.
I want to know if anyone thinks this is a bug.
Summary:
1) Start with three classes: GrandParent, Parent (extends GrandParent), Child (extends Parent).
2) Now assume that GrandParent has a method "foo" that Child didn't inherit (due to on the access permissions: private (or package-private))
3) It is possible that a different method "bar" with the same access permissions is also not inherited by Child, yet in certain circumstances, if Child has a "bar" method, it will override the method in GrandParent.
Consider the 3 classes below (pay attention to package's of the classes)
(I added in the method "foobar" to show an example of not overriding)
package p1;
public class GrandParent {
void foo(){System.out.println("GrandParent's Foo");} // package-private
void bar(){System.out.println("GrandParent's Bar");} // package-prvate
void foobar(){System.out.println("GrandParent's foobar");} // package private
}
package p2;
public class Parent extends p1.GrandParent{
public void foobar(){System.out.println("Parent's foobar");} // public
}
package p1; // back in P1 again!
public class Child extends p2.Parent {
void bar(){System.out.println("Child's Bar");}
}
Now, consider this main class which will run different variations of the code
package p1;
public class MainClass
{
public static void main(String [] args)
{
new MainClass().test();
}
private void test()
{
GrandParent gp = new GrandParent();
System.out.println("\n =========Grandparent Object========= ");
gp.foo(); // Prints "GrandParent's foo"
gp.bar(); // Prints "GrandParent's bar"
gp.foobar();// Prints "GrandParent's foobar"
Parent p = new Parent();
System.out.println("\n\n =========Paremt Object========= ");
// p.foo(); // Error, Parent did not inherit "foo" defined in Grandparent
// p.bar(); // Error, Parent did not inherit "bar" defined in Grandparent
p.foobar(); // Prints "Parent's foobar" (it didn't inherit, it just defined it)
System.out.println("\n---Upcasting Parent to GrandParent--- ");
GrandParent p_as_gp = (GrandParent) p; // notice polymorphism
p_as_gp.foo(); // Prints "GrandParent's foo"
p_as_gp.bar(); // Prints "GrandParent's bar"
p_as_gp.foobar();// Prints "GrandParent's foobar" (it didn't inherit... and it did NOT override)
Child c = new Child();
System.out.println("\n\n=========Child Object========= ");
// c.foo(); // Error, Child did not inherit "foo" which was defined in Grandparent (even though they are in the same package)
c.bar(); // Prints "Child's bar" , it didn't inherit (just like "foo" above) it just defined it itself.
c.foobar(); // Prints "Parent's foobar" (it inherited public method from Parent)
System.out.println("\n---Upcasting Child to Parent---");
Parent c_as_p = (Parent) c; // notice polymorphism
// c_as_p.foo(); // Error, Parent did not inherit "foo" defined in Grandparent
// c_as_p.bar(); // Error, Parent did not inherit "bar" defined in Grandparent
c_as_p.foobar();// Prints "Parent's foobar"
System.out.println("\n---Upcasting Child (as Parent) to GrandParent---");
GrandParent c_as_gp = (GrandParent) c_as_p; // again notice polymorphism
c_as_gp.foo(); // Prints "GrandParent's Foo"
c_as_gp.bar(); // Prints "Child's Bar" !!!!!!!!!!!!!! It OVERRODE the method, even though Child didn't inherit the method from Grand Parent!!!
c_as_gp.foobar();// Prints "GrandParent's foobar" (Paren't didn't override method)
System.out.println("\n");
}
}
To put it more briefly:
((GrandParent) new Parent()).foobar(); // this calls GrandParent's "foobar". Parent's "foobar" is visible (public), but it did not inherit "foobar"... and it did not override "foobar"
((GrandParent) new Child()).bar(); // this calls Child's "bar" !!!!! Child's "bar" is visible (package-private), but child didn't inherit "bar"... yet it DID +override+ "bar" !!!
I had always believed you had to actually inherit a method to be able to override it... Doesn't that make sense? Is it a bug?