views:

362

answers:

5

Here is my code

class Glyph { 
  void draw() { System.out.println("Glyph.draw()"); } 
  Glyph(int i) { 
    System.out.println("Glyph() before draw()"); 
    draw(); 
    System.out.println("Glyph() after draw()"); 
  } 
}  

class RoundGlyph extends Glyph { 
  private int radius = 1; 
  RoundGlyph(int r) { 
      super(r);
    radius = r; 
    System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius); 
  } 
  void draw() { 
      System.out.println("RoundGlyph.draw(), radius = " + radius); 
  } 
}  

public class PolyConstructors { 
  public static void main(String[] args) {
  new RoundGlyph(5); 
  } 
}

Output:

Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5

Why is the constructor of the superclass Glyph calling the draw method of the subclass RoundGlyph? How can I call the draw method of the superclass from the constructors of the superclass? I tried this but it didn't work....

+3  A: 

It's bad practice to call non-private or non-static methods from ctors, because call to non-private or non-static method from ctor will result in calling method in subtype, just as in your case. So, don't do this and change design of your application.

Victor Sorokin
Yes i knw now but was curious to know how and why it is working like this.
Rahul Garg
+3  A: 

Why the Constructors of super calling draw method of sub classs

This is the way that method overriding works. If a subclass has implemented a method with the same signature as its parent (or grandparent, etc), when one of its ancestors calls that method without specifying super., the sublcass's version will be called.

how i will be able to call method of super from Constructors of super

There isn't a way to specify calling my version of a method, as opposed to a subclass's version.

Please note that you shouldn't do any work in a constructor other than what is necessary to set up the class.

akf
+1  A: 

You can't. All methods are virtual in Java and you cannot specify which in the inheritance hierarchy you want to execute. The only exception is that subclasses can call their parent's methods even if they themselves override it.

If you don't want a method to be overridable, declare it as final (or private).

waxwing
+1 for noting that all methods in Java are virtual. I was suprised that none of the other answers mentioned it.
R. Bemrose
+1  A: 

The base class constructor is calling the sub class draw() method because you're creating an object of the sub class type. This is how it's supposed to work. The methods for the sub class are loaded by the class loader, not when the constructor gets called, so they're already available to be executed by the constructor. See the relevant section of the JLS for more information.

You can't call the base class draw() method from an instance of the subclass in the way you're attempting. You'd need to either not override the method in the subclass, or change your design to encapsulate Glyph instead of extending it.

Bill the Lizard
+2  A: 

I agree with the answers regarding this is bad design for constructors. But if you need to call a base-class method from inside the base-class, you need to extract the code into a not overridden method. A instantiated subclass object will always execute the overridden method.

class Glyph {
    void draw() {
        doDraw();
    }

    private void doDraw() {
        System.out.println("Glyph.draw()");
    }

    Glyph(int i) {
        System.out.println("Glyph() before draw()");
        doDraw();
        System.out.println("Glyph() after draw()");
    }
}
crunchdog