【问题标题】:Java: How constructors and methods behave with inheritanceJava:构造函数和方法如何处理继承
【发布时间】:2017-05-23 01:44:43
【问题描述】:

Java 在类构造函数和方法处理继承的方式上似乎不一致。

案例 1 - 方法:

public class HelloWorld
{
  public static void main(String[] args)
  {
    Bee b = new Bee();
    b.foo();
  }
}

class Insect {
  public void foo() {
    this.bar();
    System.out.println("Insect foo");
  }

  public void bar() {
    System.out.println("Insect bar");
  }
}

class Bee extends Insect {
  @Override
  public void foo() {
    super.foo();
    System.out.println("Bee foo");
  }

  @Override
  public void bar() {
    System.out.println("Bee bar");
  }
}

以上代码输出如下:

蜜蜂吧

昆虫 foo

小蜜蜂

注意在 Insect 的 foo() 方法中对 "this.bar()" 的调用实际上会返回并调用 Bee 的 bar() 方法(而不是调用 Insect 的 bar() 方法)。

案例 2 - 构造函数:

public class HelloWorld
{
  public static void main(String[] args)
  {
    Bee i = new Bee(1);
  }
}

class Insect {
  public Insect(int size) {
    this(size, 123);
    System.out.println("Constructor: Insect size");
  }

  public Insect(int size, int height) {
    System.out.println("Constructor: Insect size, height");
  }
}

class Bee extends Insect {
  public Bee(int size) {
    super(size);
    System.out.println("Constructor: Bee size");
  }

  public Bee(int size, int height) {
    super(size, height);
    System.out.println("Constructor: Bee size, height");
  }
}

上面的输出如下。

构造函数:昆虫大小、高度

构造函数:昆虫大小

构造函数:蜜蜂大小

注意对“this(size, 123);”的调用insect 的构造函数转到 Insect 的第二个构造函数,而不是 bee 的第二个构造函数。

总之,method 调用返回子类,而 constructor 调用留在超类中。谁能解释一下为什么?

【问题讨论】:

  • 因为方法可以被覆盖而构造函数不能。
  • JLS 8.8: "构造函数声明不是成员。它们永远不会被继承,因此不会被隐藏或覆盖"
  • 你读过关于虚拟方法或虚拟调用的文章吗?
  • 情况2不应该是编译错误吗?因为 Bee 类的构造函数上的 @Override
  • 是的,应该的。

标签: java inheritance


【解决方案1】:

除了 cmets 中关于 方法构造函数 不同的正确信息之外,您实际上是在 过度简化 事物。 p>

您看,当您编写构造函数时,您必须决定是否打算使用“同一类”构造函数(当您使用 this() 时) - 或如果你想调用一个超类构造函数(使用super())。这里没有中间立场——你必须明确这一点!

请记住:构造函数的职责是初始化相应类的对象。如果您在构造函数中调用 this(whatever)super(whatever),它会产生巨大的不同。

编译器不知道你打算做什么。因此,您必须明确说明要调用的确切 other 构造函数。

除此之外 - 像这样在此处使用 多态性 根本没有意义。您绝对希望对象初始化按照您预期发生。因为错误地初始化对象肯定会在稍后产生问题。

您使构造函数具有多态性的想法基本上意味着您在运行时确定要调用哪个构造函数。但是您已经知道您属于 X 类,并且您必须初始化一个新的 X 对象。在这里允许多态并没有什么好处。相反 - 这样做会导致非常奇怪和奇怪的问题,这些问题纯粹是运行时的!

【讨论】:

    猜你喜欢
    • 2020-08-07
    • 1970-01-01
    • 2013-03-21
    • 2011-09-09
    • 2010-12-11
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    相关资源
    最近更新 更多