0

我正在研究构造函数重载,下面是我的代码

class Philosopher {
    Philosopher(String s) {
        System.out.print(s + " ");
    }
}

public class Kant extends Philosopher {
    // insert code here
    Kant() {
        this("Bart"); //constructor overloading 
        //super("Bart"); //-->can also write this 
    }

    Kant(String s) {
        super(s);
    }

    public static void main(String[] args) {
        new Kant("Homer"); 
        new Kant();
    }
}

现在我的查询是,在 Kant 类中,它是我们正在编写 this("Bart"); 的默认构造函数;它正在调用类本身中的另一个构造函数,我们不能使用 super("Bart") 吗,它也会执行相同的功能,请告知。

4

3 回答 3

4

在这种特殊情况下,是的,您可以只使用super("Bart")- 不是在这两种情况下都是构造函数链接重载只是有多个构造函数。

然而,通常情况下,将一个类链中的所有构造函数设置为该类的“主”构造函数是一个更好的主意,该类是唯一具有super(...)调用的构造函数。这样,您在该构造函数中放置的任何逻辑都将在调用任何构造函数时执行。在这种情况下,这是无关紧要的,因为您在构造函数中没有任何其他逻辑,但通常情况并非如此。

于 2012-05-01T06:50:58.927 回答
0

我认为这更符合您所看到的内容,这是父类和子类中构造函数之间的this(...)区别super(...)

首先,我制作了这个综合测试程序并运行了它。我讨厌提出在构建时证明不正确的声明......

public class Philosopher {

  Philosopher(String s) {
    System.out.println(s);
    System.out.print("from Philosopher(String s){System.out.println(s);}...  ");
  }

  Philosopher() {
    this("whatev... ");
    System.out.print("from Philosopher(){this(\"whatev... \");}...  ");
  }
}

class Kant extends Philosopher {

  Kant(String s) {
    System.out.println(s);
    System.out.print("from Kant(String s){System.out.println(s);}...  ");
  }

  Kant() {
    this("whatev... ");
    System.out.println("from Kant(){this(\"whatev... \");}...  ");
  }

  Kant(int i) {
    super("whatev... ");
    System.out.println("from Kant(int i){super(\"whatev... \");}...  ");
  }

  public static void main(String[] args) {
    String s = "String \"s\" InMain";
    System.out.print("\n\n    new Philosopher(s);  produces:\n");
    new Philosopher(s);

    System.out.print("\n\n    new Philosopher();  produces:\n");
    new Philosopher();

    System.out.print("\n\n    new Kant(s);  produces:\n");
    new Kant(s);

    System.out.print("\n\n    new Kant();  produces:\n");
    new Kant();

    System.out.print("\n\n    new Kant(69);  produces:\n");
    new Kant(69);
  }
}

带注释的输出

当我运行它时,我得到了这个输出。我在每一行输出中穿插我自己的评论。

    new Philosopher(s);` produces
String "s" InMain
from Philosopher(String s){System.out.println(s);}...  

这里毫不奇怪,调用不引用this()orsuper()的超类的构造函数,它只运行超类的构造函数。

    new Philosopher();  produces:
whatev... 
from Philosopher(String s){System.out.println(s);}...  from Philosopher(){this("whatev... ");}...  

没有太多惊喜。 Philosopher()使用this("whatev...")this()引用Philosopher(String s)构造函数。所以两者都在这个结构中被调用 Philosopher()Philosopher(String s)

    new Kant(s);  produces:
whatev... 
from Philosopher(String s){System.out.println(s);}...  from Philosopher(){this("whatev... ");}...  String "s" InMain
from Kant(String s){System.out.println(s);}...  

这让我很惊讶!一个简单的构造函数用orKant(String s)什么也不调用,但它最终在构造一个. 每个没有显式调用父类构造函数的子类构造函数都会神奇地调用零参数父类构造函数!this()super()Kant

所以任何Kant不引用 a 的构造函数super都会表现得就像super();它的第一行一样!因此,我们具有从父级到子级的构造连续性。

    new Kant();  produces:
whatev... 
from Philosopher(String s){System.out.println(s);}...  from Philosopher(){this("whatev... ");}...  whatev... 
from Kant(String s){System.out.println(s);}...  from Kant(){this("whatev... ");}...  

Kant()里面有一个this,但没有super。所以 Java 神奇地表现得好像super()我们的构造函数中有一个权限Kant(),即使没有。

new Kant(69);  produces:
whatev... 
from Philosopher(String s){System.out.println(s);}...  from Kant(int i){super("whatev... ");}...  

所以Kant(int i)确实有对父类构造函数的显式引用。所以它的输出相对简单,因为我们Philosopher(String s)直接引用,所以我们不走Philosopher()隐式父构造函数调用给我们的额外绕道。

结论

子类构造函数总是调用父类构造函数。如果您不指定调用哪个父类构造函数,则将在子类构造函数中的任何其他代码之前调用零参数构造函数。如果您确实指定要调用哪个父类构造函数,则您可以更好地控制。

使用this和的构造函数super可以链接在一起,在一个看似简单的new Kant()对象构造过程中最多可以访问 4 个构造函数!

如果你一直读到这里,你应该得到某种奖励!有评论给我点个赞...

于 2012-05-01T23:44:49.820 回答
0

在你的情况下,你也可以打电话super("Bart")

但是,请考虑 Kant(String s)构造函数调用一些附加代码的情况。在这种情况下super("Bart")不会执行Kant(String s),因此不会调用该构造函数中的附加代码。

于 2012-05-01T06:50:39.467 回答