简体   繁体   English

在Java中用超类的construtor调用抽象方法

[英]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. 我写了一个测试,并弄明白:结果是: subclass感谢@Tim Pote的例子。

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 编辑以回应OP的评论

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. 调用超类实现的唯一时间是通过super关键字。 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 . 打印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 打印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. 我发现的一个例外是当子类提供一些“常量”信息时,例如getId()getHandledMessages()等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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