在Java中,可以调用父类';通过父类的子类的构造函数来构造父类的超类构造函数?

在Java中,可以调用父类';通过父类的子类的构造函数来构造父类的超类构造函数?,java,inheritance,constructor,Java,Inheritance,Constructor,我知道这个词有点让人困惑和奇怪,但请耐心听我说,我不知道如何用更短的词来表达 假设您有一个名为SuperBlah的类,您在名为Blah的类中继承了它,然后您将Blah继承到名为ChildBlah的类中(因此SuperBlah Blah-ChildBlah)。将super()关键字称为SuperBlah的构造函数 对那些说不的人来说,这为什么有效? 我们有一个名为BlusterBug的类,它扩展了Critter类,并在BlusterBug的构造函数中调用super。Criter没有构造函数,但Cr

我知道这个词有点让人困惑和奇怪,但请耐心听我说,我不知道如何用更短的词来表达

假设您有一个名为
SuperBlah
的类,您在名为
Blah
的类中继承了它,然后您将
Blah
继承到名为
ChildBlah
的类中(因此
SuperBlah Blah-ChildBlah
)。将
super()Blah
没有构造函数,则
ChildBlah
的构造函数中使用的code>关键字称为
SuperBlah
的构造函数

对那些说不的人来说,这为什么有效? 我们有一个名为BlusterBug的类,它扩展了Critter类,并在BlusterBug的构造函数中调用super。Criter没有构造函数,但Criter扩展的类确实有构造函数。(我故意省略了类上的其余代码)

然后在Critter类中,它没有任何构造函数

public class Critter extends Actor// omitted all the code
{
    /**
     * A critter acts by getting a list of other actors, processing that list,
     * getting locations to move to, selecting one of them, and moving to the
     * selected location.
     */
    public void act()
    {
        if (getGrid() == null)
            return;
        ArrayList<Actor> actors = getActors();
        processActors(actors);
        ArrayList<Location> moveLocs = getMoveLocations();
        Location loc = selectMoveLocation(moveLocs);
        makeMove(loc);
    }
公共类Critter扩展了Actor//省略了所有代码
{
/**
*一个小动物通过获取一个其他演员的名单,处理这个名单,
*获取要移动到的位置,选择其中一个位置,然后移动到
*选定的位置。
*/
公共无效法
{
如果(getGrid()==null)
返回;
ArrayList actors=getActors();
过程参与者(参与者);
ArrayList moveLocs=getMoveLocations();
位置定位=选择移动位置(移动定位);
makeMove(loc);
}
但是Actor类有一个构造函数

public class Actor
{
    private Grid<Actor> grid;
    private Location location;
    private int direction;
    private Color color;

    /**
     * Constructs a blue actor that is facing north.
     */
    public Actor()
    {
        color = Color.BLUE;
        direction = Location.NORTH;
        grid = null;
        location = null;
    }
公共类参与者
{
私有电网;
私人位置;
私人int方向;
私人色彩;
/**
*构造一个面向北方的蓝色演员。
*/
公共行为者()
{
颜色=颜色。蓝色;
方向=位置。北;
网格=空;
位置=空;
}

最奇怪的是?程序运行得非常好,编译器没有捕捉到任何错误!这是怎么发生的?

不,不会。它将调用
Blah
中的隐式默认构造函数
If
Blah
定义了其他构造函数(带参数),但没有
默认构造函数,则这将生成编译错误

另外,请注意构造函数不是继承的

(如果这与您的问题/想法有关)piler将为
Blah
生成一个隐式无参数构造函数,它只是
super()
——也就是说,它将调用
SuperBlah
的构造函数

因此,当
ChildBlah
的构造函数调用
super()
时,它将调用编译器为
Blah
生成的隐式构造函数,从而导致调用
SuperBlah
的构造函数。因此,在某种意义上,我认为您的问题的答案是“是”


但这只有在
Blah
没有构造函数的情况下才有效。(在实际代码中,
Critter
没有任何构造函数,所以它可以工作。)如果为
Blah
定义了任何其他构造函数,但没有可访问的无参数构造函数,那么就不会有隐式无参数构造函数,并且结果将在编译时出错。

否。构造函数在由层次结构中的中间类进行可选重写方面与方法不同。如果中间类中未实现超类的实例方法,通过
super.method()从子类调用该方法
将调用超类方法。但是必须调用层次结构中每个类的构造函数-不能跳过中间类的构造函数。

这种问题最好通过编写带有打印语句的类并进行测试来回答。我认为您可以在不到30行的代码中得到答案,一个你可以学到很多细节。每个Java类都至少有一个构造函数。如果它没有声明构造函数,那么它有一个默认构造函数,它不带参数,只包含一个
super();
调用。
public class Actor
{
    private Grid<Actor> grid;
    private Location location;
    private int direction;
    private Color color;

    /**
     * Constructs a blue actor that is facing north.
     */
    public Actor()
    {
        color = Color.BLUE;
        direction = Location.NORTH;
        grid = null;
        location = null;
    }