应该取消注释哪些行以及为什么继承

时间:2017-05-28 17:26:02

标签: java inheritance

我有一个代码段,我应该确定哪些行应该取消注释,以便编译。

问题:为什么只有9,13和10,14行有效?为什么9,14不会工作呢?我有点困惑。帮助非常感谢! (顺便说一下,选项只是取消两行代码注释)

1. // Question 3.1
2. class Car {
3.  private Car() { }
4.  protected Car(int x) { }
5. }
6. public class MG extends Car {
7.   // MG(int x) { }
8.   // MG(int x) { super(); }
9.   // MG(int x) { super(x); }
10.  // private MG(int x) { super(x); }
11.  // MG() { }
12.  // MG() { this(); }
13.  // MG() { this(6); }
14.  // MG() { super(7); }
15.  public static void main(String[] args) {
16.    new MG(7);
17.    new MG();
18. } }

我认为缺乏理解来自对私有构造函数和受保护访问修饰符的熟悉程度不够,所以我正在阅读,我也会继续尝试搞清楚。

编辑:我现在几乎得到了它,首先不能调用第8行所以8和11-14的选项都没有了。第7行 - 为什么不能要求它,例如用11号线?我相信MG(){}将被调用,但首先必须调用私有car(),错误。第12行不可能,因为我需要第11行,第13行不知道为什么,第14行不知道为什么......

3 个答案:

答案 0 :(得分:1)

我是在Ideone上写的,因为我非常确定第9行和第14行应该有效,而且他们会这样做!

在这里查看(代码)

在这个例子中唯一要记住的是,如果你不调用父构造函数,Java将以这种方式调用它" super()"。由于您的父类非参数构造函数是私有的,因此无法编译。

这就是为什么第7,8,11行是完全错误的原因。

答案 1 :(得分:1)

继承

默认情况下,子类可以访问所有父类方法,变量,构造函数。

当你要创建子类的对象时(jvm隐式调用零参数构造函数)执行第一个父类构造函数,然后执行子类构造函数。

在你的情况下,你明确地调用超类构造函数。

在构造函数中使用print语句,你会明白...

答案 2 :(得分:-1)

首先要注意几点:

首先了解一下访问修饰符:

enter image description here

关于私人构造函数:

阻止子类化(扩展)。如果只创建一个私有构造函数(有一个构造函数),则没有类可以扩展您的类,因为它无法调用super()构造函数。 read more

关于构造函数的一点点:

  • 构造函数永远不会被继承 - 它们是特定于类中的 它们被定义了。
  • 如果没有实现构造函数,则默认构造函数将被添加 隐式编译。
  • 在子类中没有调用super()编译器自动将它们添加到所有构造函数。
  • 构造作为子类的新对象时,构造函数 总是首先调用超类。
  • 构造函数调用可能是隐式或显式的。
    • 显式调用超类的构造函数:super() - 必须是子类构造函数中的第一个语句。

MG中没有任何构造函数:

在这行public class MG extends Car { eclipse中显示错误:

  

默认情况下,隐式超级构造函数Car()不可见   构造函数。必须定义一个显式的构造函数。

由于继承,您需要将值传递给父类构造函数。

对于此new MG(7);

  

构造函数MG(int)未定义

因为你在MG类中没有任何参数化构造函数。

<强>更新

你在问题​​中说过你只想知道第7,11,12,13和14号线。但我会回答所有的问题。那些寻找答案的人也可以理解

如果您取消注释第7行:

当我们创建子类的对象时,父项的构造函数总是被完成,子项的构造函数会在以后运行。

运行程序时,首先在主方法new MG(7);对象中查找MG中的匹配构造函数,即MG(int x) {}。其中有super(),编译器添加了一个。然后编译器在父类中查找默认构造函数,它找不到,因为默认构造函数是private

要解决此问题:MG(int x) {super(x);}

如果您取消注释第8行:

运行程序时,首先在主方法new MG(7);对象中查找找到的MG中的匹配构造函数。

MG(int x) {super()}

如果添加了super(),编译器将添加此项。这两者之间没有什么不同:

MG(int x) {}
MG(int x) {super()}

如果您取消注释第9行:

这条线很好(没有错误)。第一个编译器为对象(MG(int x) { super(x); })寻找构造函数(new MG(7);。然后在构造函数内部调用super(x),它有一个参数,它与父类构造函数匹配。正如我所提到的之前,父类构造函数先执行,然后子类构造函数执行。

如果您取消注释第10行:

private MG(int x) { super(x); }

访问修饰符不受影响,因为此类是子类,并且它不是任何类的父类。我们可以通过调用private构造函数来创建对象。 read more about private constructor

如果您取消注释第11行:

MG() { }

它与new MG();对象匹配。编译器添加了super()但在父类中找不到匹配的构造函数。

如果您取消注释第12行:

MG() { this(); }

首先,让我们看一下this()

  • this可以在Class的方法或构造函数中使用。
  • this用作对Method或者当前Object的引用 正在调用构造函数。
  • this关键字可用于指代当前的任何成员 来自实例Method或构造函数的对象。
  • 可以在构造函数内部使用
  • this()关键字来调用另一个关键字 在同一个类中重载了构造函数。
  • 这也称为显式构造函数调用。
  • 并且this()super()都不能在一个构造函数中使用。

所以这一行是不必要的,因为你没有任何其他MG()构造函数。 learn more about this

如果您取消注释第13行:

MG() { this(6); }

除非你有另一个MG()构造函数,否则这也是不必要的或无法调用。如果你喜欢这样:

MG(){
    this(6);
}
MG(int x){
    super(x);
}

这里发生的是当你运行程序new MG();对象找到默认构造函数并在其中调用参数化构造函数(MG(int x){})。然后在这个构造函数中获取值并将其发送到父类。

如果您取消注释第14行:

MG() { super(7); }

new MG();与costructor匹配,并在其中将值7传递给父类参数化构造函数。

完成。