2016-09-26 97 views
4

我刚刚开始讲述Java的故事,但是我对Python有一些OOP体验。我有以下的类层次结构:覆盖java中的子类中的参数化构造函数

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编译器要我在子类中定义构造函数?

+0

的问题,如“为什么语言这种方式工作”只能由回答语言的设计师,而不是这个社区。在Java中,构造函数不会被继承。这是事实。除此之外的任何事情都是猜测。 – RealSkeptic

+1

[Java Constructor Inheritance](http://stackoverflow.com/questions/1644317/java-constructor-inheritance) – shmosel

+0

“是否有任何特殊原因,为什么java编译器要我在子类中定义构造函数?”你的意思是除了James Gosling和Java标准委员会之外的其他任何理由认为这种方式更好?不,没有一个。 –

回答

4

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

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

既然你尝试用一个参数来实例B级,您必须声明适当的构造函数调用您所选择的父类的构造函数:

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

您需要声明Parametrised构造在B类并呼吁从中超级如果你不想初始化任何东西在你的类B.

喜欢的东西:

import java.util.*; 

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

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

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() { 

    } 
} 
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 

希望这是明确的