在 java 中覆盖子 类 中的参数化构造函数
overriding parameterized constructors in sub-classes in java
我的故事才刚刚开始 Java,但是我对 Python 有一些 OOP 经验。我有以下 class 层次结构:
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
我的期望是,因为已经在基础 class 中定义了所需的构造函数,所以不需要再定义另一个构造函数。为什么我需要为 sub-class 定义一个,因为除了调用 super()
之外它们没有做任何特别的事情?有什么特殊原因,为什么 java 编译器要我在子 class 中定义构造函数?
当您实例化 class 时,必须调用 class 的构造函数。
当 Java class 没有构造函数时,编译器会自动生成一个无参数构造函数,它允许您实例化 class 不带参数(在您的示例中,它允许 new B()
).
由于您尝试使用参数实例化 B class,因此您必须声明一个适当的构造函数来调用您选择的超级 class 构造函数:
public B(Map dict) {
super(dict);
}
如果您不想在 class B 中初始化任何内容,则需要在 class B 中声明参数化构造函数并从中调用 super。
类似于:
import java.util.*;
class B extends A
{
B(Map dict) {
super(dict);
}
}
为什么构造函数不被继承?构造函数用于初始化对象,通常在从 class 继承时,您倾向于使用通用功能但创建可能会有所不同,因此扩展构造函数也有什么用,您将只有一个超级 class 的副本,在这种情况下,将所有常用功能集中在一个 class 中并拥有一个包含不同功能的实用程序 class 是更好的做法。
In Java - 当您使用构造函数扩展某些 A-class 时,B-subclass 的构造函数始终必须调用它。如果 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,但是我对 Python 有一些 OOP 经验。我有以下 class 层次结构:
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
我的期望是,因为已经在基础 class 中定义了所需的构造函数,所以不需要再定义另一个构造函数。为什么我需要为 sub-class 定义一个,因为除了调用 super()
之外它们没有做任何特别的事情?有什么特殊原因,为什么 java 编译器要我在子 class 中定义构造函数?
当您实例化 class 时,必须调用 class 的构造函数。
当 Java class 没有构造函数时,编译器会自动生成一个无参数构造函数,它允许您实例化 class 不带参数(在您的示例中,它允许 new B()
).
由于您尝试使用参数实例化 B class,因此您必须声明一个适当的构造函数来调用您选择的超级 class 构造函数:
public B(Map dict) {
super(dict);
}
如果您不想在 class B 中初始化任何内容,则需要在 class B 中声明参数化构造函数并从中调用 super。
类似于:
import java.util.*;
class B extends A
{
B(Map dict) {
super(dict);
}
}
为什么构造函数不被继承?构造函数用于初始化对象,通常在从 class 继承时,您倾向于使用通用功能但创建可能会有所不同,因此扩展构造函数也有什么用,您将只有一个超级 class 的副本,在这种情况下,将所有常用功能集中在一个 class 中并拥有一个包含不同功能的实用程序 class 是更好的做法。
In Java - 当您使用构造函数扩展某些 A-class 时,B-subclass 的构造函数始终必须调用它。如果 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
希望这是清楚的