【问题标题】:Is there a way I can call a parent class constructor that takes parameters from a child class that does not have a constructor of it's own?有没有一种方法可以调用父类构造函数,该构造函数从没有自己的构造函数的子类中获取参数?
【发布时间】:2019-01-24 03:49:52
【问题描述】:

众所周知,父类必须在子类之前构造;并且如果父类的构造函数带参数,那么必须显式调用父类的构造函数。我的问题是,如果子类本身没有构造函数,如何调用从子类显式获取参数的父类构造函数?

public class A {
public String text;

public A(String text) {
    this.text = text;
}
}


public class B extends A {
// Now I must call the constructor of A explicitly (other wise I'll get a
// compilation error) but how can I do that without a constructor here?
}

【问题讨论】:

  • 为什么你不想在 B 中有一个构造函数?
  • 如果您没有说明为什么要在 B 中没有构造函数,这只是一个 XY problem
  • 这只是一种假设情况。
  • 感谢您的快速接受,并对 super() 和 super.someMethod() 造成的混淆感到抱歉 :-)
  • @GhostCat 感谢您的回答并澄清每个类都有一个构造函数,即使我没有明确地创建一个。在我意识到我的问题的荒谬之前,我肯定需要了解编译器会自动生成一个。

标签: java inheritance constructor super


【解决方案1】:

答案是:你不能!

如果超类有一个无参数构造函数,编译器也可以在子类中为你添加一个类似的构造函数。

但是当超类需要参数时,编译器不知道这些参数应该从哪里来。

所以:考虑为超类添加一个无参数构造函数,它可以调用另一个构造函数并传递某种默认值。或者,您可以在派生类中执行相同的操作。

仅作记录:没有没有构造函数的 Java 类。只是编译器可能会在幕后为您创建一个。从这个角度来看,你的问题没有多大意义。

【讨论】:

  • 为什么我不能只写 super("text");或 super.A("text");在没有构造函数的 B 类中?那么编译器不知道要传递给参数的值吗?
  • 因为你不能。这就是规则。关键字“super”只能用作构造函数中的第一条语句。其他任何地方都不允许这样做。学习 Java 的基本规则,而不是试图发明自己的规则!除此之外,任何语句都需要在方法的主体中,您不能将它们放在类中的任何位置。
  • @MatthewS。因为在对象构造的时候调用了构造函数..如果你在其他地方调用 super ,那就太晚了
  • 好点:对象在创建时如何初始化有一个明确定义的顺序!
  • @MatthewS。 supersuper() 是有区别的,后者会调用构造函数,所以只能放在构造函数的第一行,不能放在其他任何地方
【解决方案2】:

您收到编译错误,因为类 A 中没有默认构造函数。您可以在B 中创建一个无参数构造函数并将一些默认文本传递给A 的构造函数,或者在A 中创建一个无参数构造函数。

public B() {
    super("some default text"); //will call public A(String text)
}

【讨论】:

  • 是的,我想知道是否可以从B类调用A类中的构造函数,而无需在B类中创建构造函数。
  • 你误解了他的问题。他知道为什么会出现编译错误。
  • @MatthewS。这是不可能的
  • @MatthewS。构造函数不像实例方法。必须调用构造函数来创建对象。然后你可以调用该对象的任何方法on。您不能将调用父构造函数部分 (super(..)) 移动到任何方法,因为您首先需要一个对象来调用该方法(鸡和蛋的问题)。在考虑静态方法时,您也不走运。没有与静态方法关联的 instanceobject。所以,super 在那里不起作用。
  • @MatthewS。对不起,你是对的。在调用超类构造函数的上下文中,我的意思是 super。 super() 与 super.someMethod() 完全不同!
【解决方案3】:

如果你不愿意直接调用父构造函数,你只需要在子类中添加一个参数相同的构造函数来调用父构造函数。

public class A { 
    public String text; 

    public A(String text) 
    { 
        this.text = text; 
    } 
} 

public class B extends A 
{
    public B(String text)
    {
        super(text);
    }
}

【讨论】:

  • 什么是"直接调用父构造函数"如果不是这个?
  • 我将该问题解释为误解了为什么B foo = new B("test"); 不起作用(没有在 B 中定义构造函数)并期望它只是直接调用父构造函数。
猜你喜欢
  • 1970-01-01
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 2020-05-02
  • 1970-01-01
  • 2012-11-26
相关资源
最近更新 更多