简体   繁体   中英

Calling an abstract method in super class's construtor in Java

Since the subclass is not constructed yet, is it unsafe to call an abstract method in a super class constructor?

However, if the method's behaviour does not depend on the constrction of subclass, eg just return a constant with regard to the subclass, is it still unsafe or will it work reliably?

Moreover, if it works, how to do it if I do not want to make the super class abstract?

Update: for last question

public class SuperClass {
      public SuperClass() {
          System.out.println(getValue());
      }   

      public String getValue() {
          return "superclass";
      }   

      public static void main(String[] args) {
           new SubClass();
      }

}


class SubClass extends SuperClass {
      public SubClass() {
           super(); // Comment out this or not  will not affect the result
      }   

      public String getValue() {
           return "subclass";
       }   
}

I wrote a test, and figure it out: the result is : subclass Thanks to @Tim Pote's example.

It is generally (though not necessarily) considered unsafe. As you said, the superclass may not be fully constructed, and therefore won't be ready to handle all of the calls a subclass might make in its overridden method.

However, in the case that all subclasses simply return a constant that isn't dependent on any other method, then it should be fine. The only downside is that you can't guarantee that a subclass will override that method in an appropriate manner.

In regards to your last question: this isn't an issue of an abstract vs. concrete superclass. This is an issue with calling overridable methods in a constructor. Abstract vs. concrete is beside the point.


Edit in response to the OP's comment

I'm not certain what you mean by "polymorphiscly". Calling a virtual method always invokes the sub-most implementation. The only time a superclasses implementation is invoked is via the super keyword. For example:

public class SuperClass {
  public SuperClass() {
    System.out.println(getValue());
  }   

  public String getValue() {
    return "superclass";
  }   

  public static void main(String[] args) {
    new SubClass();
  }   

  public static class SubClass extends SuperClass {
    public String getValue() {
      return "subclass";
    }   
  }   
}

prints subclass .

And this:

public class SuperClass {
  public SuperClass() {
    System.out.println(getValue());
  }   

  public String getValue() {
    return "superclass";
  }   

  public static void main(String[] args) {
    new SubClass();
  }   

  public static class SubClass extends SuperClass {
    public String getValue() {
      return super.getValue() + " subclass";
    }   
  }   
}

prints superclass subclass

As others have explained there is an inherent risk in calling abstract methods in super class constructor.

The one exception I have found is when the subclass provides some "constant" information, eg getId() , getHandledMessages() and suchlike.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM