"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();
目前正在研究"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();