在java中重写子类中的参数化构造函数
我只是从Java开始我的故事,但是我有一些Python的OOP经验。我有以下类层次结构:在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 =
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标准委员会为什么采用这种设计?旁注:不要使用原始类型。