在java中重写子类中的参数化构造函数

在java中重写子类中的参数化构造函数,java,oop,inheritance,constructor,constructor-inheritance,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 =

我只是从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编译器为什么要我在子类中定义构造函数,有什么特殊原因吗?

当您实例化一个类时,必须调用该类的构造函数

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

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

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

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

比如:

import java.util.*; 

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

为什么构造函数不被继承?构造函数用于初始化对象,通常在从类继承时,您倾向于使用公共功能,但创建可能有所不同,因此扩展构造函数也有什么用,您将只是拥有一个超级类的副本,在这种情况下,更好的做法是将所有公共功能放在一个类中,并拥有一个包含不同功能的实用程序类。

在Java中-当您使用构造函数扩展某个a类时,B子类的构造函数始终必须调用它。如果A得到0个参数-您不必写任何东西-编译器将自动调用它。如果有更多参数,则必须使用
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() {

    }
}

默认构造函数是在没有定义构造函数时自动创建的。必须在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

希望这是清楚的

像“语言为什么以这种方式工作”这样的问题只能由语言设计者来回答,而不是由这个社区来回答。在Java中,构造函数不是继承的。这是事实。除此之外的任何事情都是猜测。可能重复“有什么特殊原因,为什么java编译器要我在子类中定义构造函数?”的意思是除了James Gosling和java标准委员会认为这样更好之外的任何其他原因?不,没有。@AdrianColomitchi,我想知道James Gosling和Java标准委员会为什么采用这种设计?旁注:不要使用原始类型。