覆盖java

时间:2016-09-26 06:47:23

标签: java oop inheritance constructor constructor-inheritance

我刚刚用Java开始我的故事,但是我对Python有一些OOP经验。我有以下类层次结构:

class A {
   public A() {};
   public A(final java.util.Map dict) {};
}

class B extends A {
}

public class Main {
  public static void main() {
     java.util.Map d = new java.util.HashMap();
     B b = new B(d);
  }
}

附加的代码会导致以下错误:

Main.java:16: error: constructor B in class B cannot be applied to given types;
     B b = new B(d);
           ^
  required: no arguments
  found: Map
  reason: actual and formal argument lists differ in length
1 error

我期望的是,因为必需的构造函数已经在基类中定义,所以不需要定义另一个构造函数。为什么我需要为子类定义一个,因为除了调用super()之外,它们没有做任何特殊的事情?有什么特别的原因,为什么java编译器要我在子类中定义构造函数?

5 个答案:

答案 0 :(得分:4)

实例化类时,必须调用该类的构造函数。

当Java类没有构造函数时,编译器会自动生成一个无参数的构造函数,它允许您实例化没有参数的类(在您的示例中,它允许new B())。

由于您尝试使用参数实例化B类,因此必须声明一个适当的构造函数来调用您选择的超类构造函数:

public B(Map dict) {
    super(dict);
}

答案 1 :(得分:1)

如果您不想初始化B类中的任何内容,则需要在B类中声明Parametrised构造函数并从中调用super。

类似的东西:

import java.util.*; 

class B extends A
{
    B(Map dict) {
         super(dict);
     }
}

答案 2 :(得分:1)

在Java中 - 当您使用构造函数扩展某个A类时,B子类的构造函数始终必须调用它。如果A得到0参数 - 你不必写任何东西 - compiller会自动调用它。如果有更多参数,则必须使用super()将它们传递给基础构造函数。以下是一些例子:

public class A {
    public A(int something) {

    }
}

public class B extends A {
    public B(int something) {
        super(something);
    }
}

public class C extends A {
    public C() {
        super(999);
    }
}

//--------------------------------------------//

public class A {
    public A() {

    }
}

public class B extends A {
    public B(int something) {
        super();
    }
}

public class C extends A {
    public C(int something) {
    }
}

public class D extends A {
    public D() {
        super();
    }
}

public class E extends A {
    public E() {

    }
}

答案 3 :(得分:1)

默认构造函数是在没有定义构造函数时自动创建的。你必须在B中添加默认构造函数来调用A的默认构造函数。

因此您的代码需要以下

class B extends A
{
    B(){
      super();  // calling super class  default constructor
    }
    B(Map dict) {
        super(dict); // calling super class single parameter(map) constructor
    }
}

那样

B b = new B(); //invokes A's Default Constructor
B b = new B(d); //invokes A's Parameter Consturctor

希望这很清楚

答案 4 :(得分:0)

为什么构造函数不会被继承?构造函数用于初始化对象,通常当从类继承时你倾向于使用通用功能但创建可能不同,那么扩展构造函数的用途是什么,你将只是重复一个超级class,在这种情况下,将所有常用功能放在一个类中并使用包含不同功能的Utility类是更好的做法。