Java 如何打破超类构造函数链?

Java 如何打破超类构造函数链?,java,class,inheritance,Java,Class,Inheritance,上面的代码产生以下结果: class Animal { protected Animal(){ System.out.println("ANIMAL CONSTRUCTOR"); } public void move(){ System.out.println("ANIMAL Move"); } } class Dog extends Animal{ public Dog(){ System.out.pri

上面的代码产生以下结果:

class Animal {
    protected Animal(){
        System.out.println("ANIMAL CONSTRUCTOR");
    }
    public void move(){
        System.out.println("ANIMAL Move");
    }
}

class Dog extends Animal{
    public Dog(){
        System.out.println("Dog Constructor");
    }
    public void move(){
        System.out.println("Dog move");
    }

}


public class Test {
    public static void main(String args[]){
    Dog d = new Dog();
    d.move();
    }
}
似乎在创建dog实例时,默认情况下它也会调用Animal构造函数(隐式)

这很奇怪,因为我想显式调用
super()
可以完成同样的工作

有没有办法打破这个构造函数链,让我的狗实例只调用狗构造函数

如果没有,原因是什么

似乎在创建dog实例时,默认情况下它也会调用Animal构造函数(隐式)

这很奇怪,因为我认为显式调用super()可以完成同样的工作

可以,是的,但是如果不可以,编译器会在子类构造函数的开头插入对
super()
(不带参数)的调用。允许显式执行此操作的原因是,您可能希望调用接受参数的超类构造函数

有没有办法打破这个构造函数链,让我的狗实例只调用
dog
constructor

没有

如果没有,原因是什么

因为
Dog
是一个(n)
Animal
,因此
Animal
类必须有机会初始化所创建对象的
Animal
特定特征

考虑:

ANIMAL CONSTRUCTOR 
Dog Constructor
Dog move
当您构造一个
Dog
实例时,在内存中它看起来是这样的:

class Animal {
    private Something useful;

    Animal() {
        this.useful = /*...something useful...*/;
    }
}

class Dog extends Animal {
    private String breed;

    Dog(String breed) {
        this.breed = breed;
    }
}
+-------------+ |狗| +-------------+ |有用:| |品种:| +-------------+
Dog
实例是由
Animal
定义的内容和
Dog
定义的内容的组合


现在,假设从未调用过
Animal
的构造函数:
有什么有用的值?对!
null
(因为我将其声明为对象类型)。但是
Animal
的代码非常清楚地期望构造函数将
设置为有用的东西。如果我们能够以某种方式绕过
Animal
的构造函数,我们将破坏类。

在实例化子类时,无法阻止调用
Animal
构造函数。本质上,这是因为基类可能也包含需要设置的字段

(请注意,隐式基类
java.lang.Object
的构造函数也被调用。您的问题更多的是关于继承继承继承权中某个地方的“缺少构造函数”)


如果
Animal
不包含任何字段,则可以将其设置为
接口。那么它就没有构造函数了。以这种方式使用接口允许您在非动物对象(如车辆)上定义类似于移动的方法。然后,您将遇到一个称为composition的编程范例。

我认为这可能是一个XY问题。为什么您不希望调用
Animal
构造函数呢?“为什么”将这个问题与最初标识为重复的问题区分开来。也就是说,几乎可以肯定的是,这个问题的早期版本是可以关闭并指向的。这个问题大部分(完全?)是通过结合来回答的。因此
super()
被用来明确它是继承的,或者是从许多其他构造函数中选择的?@KeonKim:是的
super()
(字面意思,没有参数)纯粹是风格问题。举例来说,我总是这样做,正是因为这些原因:为了弄清楚发生了什么,特别是我称之为无参数版本。但有些人相当合理地认为我不应该这样做,因为编译器总是这样做,所以他们发现看到它显式编写时会感到不舒服。当您调用
super(with,args,here)
时,这当然是必需的,因为编译器永远不会为您这样做。(即使超类没有无参数构造函数也不行。) +-------------+ | Dog | +-------------+ | useful: ... | | breed: ... | +-------------+