"extends" 实际上是做什么的?

What does "extends" actually do?

目前正在研究"class abstraction"和"extension"的概念,一直在想:
"If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?"

我理解扩展实例将先前的抽象 class 实例化为扩展的抽象并尝试调用默认构造函数,但一直想知道为什么它会出错。

是构造函数参数化了还是空构造函数不存在?

extends 关键字是否调用了类似于此的内容?

Object myClass = new AbstractClass();

缺少的参数是它给出错误的原因,所以类似这样的东西是正确的

Object myClass = new AbstractClass(int foo,float boo);

如果是这样,super 关键字本质上是不是,如果你允许我使用这个术语,"put" 括号中给出的参数 "inside" 构造函数?

如果不是这样,我哪里错了? 实际上 是如何工作的?

初始化对象时,总是会调用构造函数。即使您没有定义一个构造函数,也会有一个没有任何参数的默认构造函数。因此,如果您在抽象 class 中定义构造函数,则必须使用 super() 调用该构造函数。

如果您不定义任何构造函数,那么它将被隐式调用为默认构造函数。

"If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?"

因为 super class 说它必须是使用声明的构造函数的构造函数并且没有其他方法。这适用于每个扩展 class - 必须调用所需的构造函数。

当您声明其他构造函数而不是默认构造函数时,任何 class 都会发生同样的情况。例如,有

public class A{
   //no default no-arg ctor here
   public A(String name){
       ....
   }

}

public class B{
  //default no-arg ctor will be created
}

那么

  B b=new B();
    A a=new A(); //// INVALID!
    A a=new A("foobar"); // yeah that is it

扩展 classes 时同样适用。要构造子实例,您必须先"internally create parent instance" 调用super.constructor。由于没有默认构造函数,因此必须使用任何显式声明的超构造函数。

在这种情况下,您应该将 extends 关键字视为只是说 class 是另一个 class 的子 class,并且什么都不做别的。并且存在管理子classes 和超级classes 应该如何工作的规则。

构造子class时,必须先构造它的超class。例如,要创建一个 Bird,您必须先创建一个 Animal。这是有道理的,不是吗?在代码中演示这一点:

class Animal {
    public Animal() {
        System.out.println("Animal");
    }
}

class Bird extends Animal {
    public Bird() {
        System.out.println("Bird");
    }
}

new Bird()会先打印Animal然后Bird,因为Animal's constructor is called first, and then the Bird constructor. So actually, the Bird constructor implicitly calls the superclass'构造函数。这可以写成:

public Bird() {
    super();
    System.out.println("Bird");
}

如果超级 class 没有无参数构造函数会怎样?假设 Animal 的构造函数现在将 String name 作为参数。您仍然需要先调用 superclass' 构造函数,但是 super() 不会起作用,因为 super() 需要一个字符串参数!

因此,编译器给你一个错误。这可以通过使用参数 .

调用 super() 显式 来解决

If I declare a parametrized constructor inside my abstract class why won't extension on another class work unless I declare myself the constructor with the super keyword invoking the parameters of the abstract class's constructor?

AbstractClass 中没有可用的默认构造函数,因为您定义了参数化构造函数。如果您不自己定义构造函数,则会隐式创建一个不带参数的默认构造函数。您现在可以手动添加这样的一个,或者您需要使用 only 可用的构造函数(已参数化)和 super().


不带参数定义构造函数的代码示例:

class AbstractClass {
    AbstractClass() {} // added manually since not created implicitly
    AbstractClass(int foo, float boo) {}
}
class RealClass extends AbstractClass {
    RealClass() { } // calls super() implicitly
}
AbstractClass myClass = new RealClass();

使用参数调用 super() 的代码示例:

class RealClass extends AbstractClass {
    RealClass() {
        super(1, 2);
    }
}
class AbstractClass {
    AbstractClass(int foo, float boo) {}
}
AbstractClass myClass = new RealClass();