package ibm;
public class TestConstructor{
public static void main(String[] args) {
Drived drived=new Drived();
System.out.println(drived.memeber);
}
}
class Base {
public Base(){
System.out.println("base constructor");
preprocess();
}
public void preprocess(){
System.out.println("base invoked");
}
}
class Drived extends Base{
public String memeber="set the string";
public Drived(){
System.out.println("drived constructor");
System.out.println(memeber);
memeber="set in constructor";
}
@Override
public void preprocess(){
System.out.println("drived invoked ");
memeber="set in proprocess ";
}
}
请问以上程序的打印输出什么?
base constructor
drived invoked
drived constructor
set the string
set in constructor
程序的执行顺序是这样的;
1 进入Drived 构造函数。
2 Drived 成员变量的内存被分配。
3 Base 构造函数被隐含调用。
4 Base 构造函数调用preprocess(),这里调用的是Drived的preprocess()(多态性)。
5 Drived 的preprocess设置memeber值为 “set in proprocess”。
6 Drived 的成员变量初始化被调用。
7 执行Drived 构造函数体。
Java中的声明和初始化不能看成一体的。在C++的世界中,C++并不支持成员变量在声明的时候进行初始化,其需要你在构造函数中显式的初始化其成员变量的值,看起来很土,但其实C++用心良苦。在面
向对象的世界中,因为程序以对象的形式出现,导致了我们对程序执行的顺序雾里看花。所以,在面向对象的世界中,程序执行的顺序相当的重要 。
下面是对上面各个步骤的逐条解释。
进入构造函数。
为成员变量分配内存。
除非你显式地调用super(),否则Java 会在子类的构造函数最前面偷偷地插入super() 。
调用父类构造函数。
调用preProcess,因为被子类override,所以调用的是子类的。
于是,初始化发生在了preProcess()之后。这是因为,Java需要保证父类的初始化早于子类的成员初始化,否则,在子类中使用父类的成员变量就会出现问题。
正式执行子类的构造函数(当然这是一个空函数,居然我们没有声明)。
你可以查看《Java语言的规格说明书》中的 相关章节 来了解更多的Java创建对象时的细节。
C++的程序员应该都知道,在C++的世界中在“构造函数中调用虚函数”是不行的,Effective C++ 条款9:Never call virtual functions during construction or destruction,Scott Meyers已经解
释得很详细了。在语言设计的时候,“在构造函数中调用虚函数”是个两难的问题。
1 如果调用的是父类的函数的话,这个有点违反虚函数的定义。
2 如果调用的是子类的函数的话,这可能产生问题的:因为在构造子类对象的时候,首先调用父类的构造函数,而这时候如果去调用子类的函数,由于子类还没有构造完成,子类的成员尚未初始化,这
么做显然是不安全的。
C++选择了第一种,而Java选择了第二种。
C++类的设计相对比较简陋,通过虚函数表来实现,缺少类的元信息。
而Java类的则显得比较完整,有super指针来导航到父类。
原文来自 http://blog.csdn.net/haoel/article/details/4319793
分享到:
相关推荐
了解和熟练使用构造方法是Java面向对象编程的基础,下面将详细阐述Java构造方法的相关知识点。 一、构造方法的作用 构造方法的主要任务是在创建对象时设置对象的初始状态,为对象成员变量赋值。当一个类被实例化时...
Java构造方法是面向对象编程中的一个关键概念,用于初始化新创建的对象。在Java类中,构造方法是一个特殊的方法,它的名字必须与类名完全相同,没有返回类型,甚至不包括void关键字。当我们创建一个类的新实例时,...
总的来说,Java中带有不同构造方法的程序内存分析涉及构造方法的选择、内存的分配(包括栈和堆)、对象的初始化以及垃圾回收机制的理解。通过深入研究这些概念,开发者可以更好地控制和优化程序的内存使用,提高程序...
### Java构造方法详解 #### 一、构造方法基础概念 构造方法是Java中一种特殊的方法,主要用于初始化新创建的对象。每个类至少有一个构造方法。如果程序员没有显式地定义构造方法,Java编译器会自动为类添加一个无...
4. **作用**:构造方法的主要任务是初始化对象的状态,通过给实例变量赋值。 5. **参数**:构造方法可以带有参数,这样可以根据不同的参数值创建具有不同初始状态的对象。这称为重载构造方法,即在同一个类中定义多...
在Java编程语言中,构造器(Constructor)是一个特殊的方法,主要负责对象的初始化工作。当创建一个新的类实例时,构造器会被自动调用。构造器的名称必须与类名完全相同,且没有返回类型,包括void。理解并熟练运用...
总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和实例初始化块、构造函数、成员变量初始化以及继承关系的影响。这个demo是学习和理解这些概念的重要工具,通过实际操作可以加深对Java内存管理和对象生命...
3. **静态成员变量与实例成员变量的初始化顺序** ```java public class TestOrder { // 静态成员变量初始化 public static TestA a = new TestA(); // 静态初始化块 static { System.out.println("静态初始...
Java构造方法是一种特殊的方法,它是一个与类同名且没有返回值类型的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也...
在Java编程语言中,初始化块是程序执行时用于初始化对象或类的重要机制。这里我们将深入探讨两种类型的初始化块:静态初始化块(Static Initializer Block)和对象初始化块(Instance Initializer Block)。这两种...
下面详细解析Java构造方法的特性和使用方法。 构造方法的特性: 1. 方法名与类名相同:构造方法的名字必须与类名完全相同,这是Java语法规定的一部分,便于编译器识别并自动调用构造方法。 2. 构造方法无返回类型:...
构造方法可以用来初始化与每个对象有关的变量。在Java中,构造方法是与类名称相同的公开的方法成员。如果用户没有显式定义构造方法,则使用系统给定的默认构造方法。系统默认的构造方法除了创建一个空对象外不会完成...
当我们谈论“Java类继承初始化顺序”时,涉及到的关键知识点包括构造器、成员变量的初始化、super关键字以及方法的覆盖。 首先,了解类初始化的顺序至关重要。当创建一个子类实例时,初始化过程遵循以下步骤: 1. ...
静态初始化块不能访问非静态成员,包括实例属性和实例方法,因为它们依赖于对象实例,而静态初始化块在类加载时并没有对象存在。 类的初始化顺序如下: - 当Java创建一个对象时,先为对象的所有属性分配内存。 - ...
### Java中对象创建、初始化与引用详解 #### 一、Java对象、引用及创建过程 在Java中,对象是程序的基本单位,它包含了属性(成员变量)和行为(方法)。对象是由类创建出来的实例,而类则是一组具有相同属性和...
总结,Java子类构造方法的使用涉及到继承、初始化、方法调用等多个概念。正确理解和运用这些知识点对于编写健壮的Java程序至关重要。通过熟练掌握这些内容,开发者可以更好地设计和实现类的层次结构,提高代码的复用...
重载构造方法的目的是提供多种初始化对象的能力,使程序员可以根据实际需要选用合适的构造方法来初始化对象。程序源代码如下。 2、使用选择语句 程序功能:使用if...else 语句构造多分支,判断某一年是否为闰年。...
构造方法是一个特殊的方法,其名称与所属类的名称完全相同,且没有返回类型。它的主要任务是对新创建的对象进行初始化,确保每个对象在诞生时都有一个确定的状态。 在Java中,构造方法的调用是自动进行的,当通过`...