假设我有三节课:
class A {
A() {
// super();
System.out.println("class A");
}
}
class B extends A {
B() {
// super();
System.out.println("class B");
}
}
class C extends B {
public static void main(String args[]) {
C c = new C(); //Parent constructor will get called
}
}
当我创建类C的实例时,它将调用超类的构造函数。那么,是否有多个对象正在创建?如果仅创建一个对象,那么super()像另一个类的构造函数如何?super()方法是否在内部创建对象?我所知道的是,构造函数也是一种方法(我可能错了)。
我的问题是:
好问题。您要探究的是Java如何 初始化对象 -涉及许多步骤。
我知道构造函数也是一种方法(也许我错了)。
几乎是正确的。构造函数是一种特殊的方法。如果您反编译一个类文件,则会看到构造函数被重命名为<init>
。<init>
与其他方法的处理方式不同,例如,除非通过使用关键字new
or,否则不能显式调用它super
。这是如此基础,以至于它是在JVM本身中实现的,而不是用Java语言定义的。
在这种情况下,将创建多少个对象。
创建了一个对象-的实例C
。
C
是另外地和同时的一个实例B
和实例A
,并且还Object
。
如果创建了一个对象,则在内部如何
super()
调用Parent类Constructor。Super如何调用父类的构造函数。
这是我们进行初始化的地方-初始化是JVM如何创建对象的新实例并设置所有成员值-特定类的成员值和超类的成员值。涉及几个阶段:
A
,B
以及C
。 注意, 这解释了问题的一个方面:基类及其子类的构造函数如何更新或引用相同的对象- 所有类的实例的所有成员都一个接一个地存储在同一块内存中 。 int
和float
成员将设置为0和0.0f。 private int a = 10;
private int b = a * 5;
private String c = Singleton.getInstance().getValue();
private int a = b * 5; // Forward reference; won't compile
private int b = 10;
private int a;
private int b = 1;
{
// Initization occurs after b but before c.
// c cannot be referenced here at all
int i = SomeClass.getSomeStatic();
a = i * 2;
}
private int c = 99;
执行的构造函数C
。构造函数必须直接从超类调用构造函数,否则编译器将自动添加super()
为构造函数的第一行。这意味着构造函数严格按顺序执行:
Object
A
B
C
现在,该对象已初始化并可以使用。如果使用实例方法初始化值,则可能会做一些危险的事情:
public class Wrong {
int a = getB(); // Don't do this!
int b = 10;
public int getB() {
return b;
}
}
在这里,a
被初始化为0
。这是因为在getB()
调用该点时,Java已将值清除为b
默认值(0
),但尚未10
在初始化的第二阶段将其设置为。
总而言之-只有一个对象,并且它是分阶段创建和初始化的。在那些阶段中,根据定义,对象没有完全定义。
主要内容:多继承下的构造函数,命名冲突在前面的例子中,派生类都只有一个基类,称为 单继承(Single Inheritance)。除此之外, C++也支持 多继承(Multiple Inheritance),即一个派生类可以有两个或多个基类。 多继承容易让代码逻辑复杂、思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java、 C#、 PHP 等干脆取消了多继承。 多继承的语法也很简单,将多个基类用逗号隔开即可。例如已声明了类A
创建对象的几种方式 通过Object <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>01_Object构造函数模式</title> </head> <body> <!-- 方式一: Object构造函数模式 * 套路: 先创建空Object对象, 再动态添加属性/方法 * 适用场景
在面向对象的程序设计中,定义一个新的 class 的时候,可以从某个现有的 class 继承,新的 class 称为子类,而被继承的 class 称为基类、父类或超类。 Python 中继承的语法如下: class Parent: pass class Child(Parent): pass 在第 1 行,定义了父类 Parent; 在第 4 行,定义了子类 Child,语法
继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗; Bat - 蝙蝠; Parrot - 鹦鹉; Ostrich - 鸵鸟。 如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次: 但是如果按照“能跑”和“能飞”来归类,我们就应该设计出这样的类的层次: 如果要把上面的两种分类都包含进来
继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗; Bat - 蝙蝠; Parrot - 鹦鹉; Ostrich - 鸵鸟。 如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次: ┌───────────────┐ │
FAQs in section [24]: [24.1] 如何表示“私有继承”? [24.2] 私有继承和组合(composition)有什么类似? [24.3] 我应该选谁:组合还是私有继承? [24.4] 从私有继承类到父类需要指针类型转换吗? [24.5] 保护继承和私有继承的关系是什么? [24.6] 私有继承和保护继承的访问规则是什么? 24.1 如何表示“私有继承”? 用 : priv