`

父类是抽象类的初始化过程的思考

    博客分类:
  • java
 
阅读更多
1. 抽象类不能够被实例化,
2. 子类对象在实例化的时候会追溯父类的构造方法,一直追溯到Object,创建所有父类的实例
3. 我在Eclipse环境下JDK6.0 update 13,写了一个抽象类,可以在里面添加构造方法。

问题:
1. 当子类的父类为抽象类时,构造方法如何追溯?抽象类作为父类也会创建实例么?
2. 抽象类中的构造方法是怎么回事?为什么有构造方法却不能实例化?
回答:
“子类对象在实例化的时候会追溯父类的构造方法,一直追溯到Object,创建所有父类的实例”这个前提是错误的,“溯父类的构造方法”
并不是会“创建所有父类的实例”,只会创建子类的一个实例。
1、子类在创建实例后,类初始化方法会调用父类的初始化方法(除了java.lang.Object类,因为java.lang.Object类没有父类),而这种调用会逐级追溯,直到java.lang.Object的初始化方法。
这个地方我说的是初始化方法,而不是构造方法,因为构造方法是相对于java源程序而言,而编译后的class文件是初始化方法即"<init>"方法(红色部分为方法名),初始化方法是由java源程序的三个部分组成的,一个部分是成员字段后的直接的初始化语句,例如private int i=0;private Date date=new Date();等等,第二个部分是由初始化块组成,例如:
Java code
publicclass Test{privateint i=0;//初始化第一部分 //以下大括号内为初始化第二部分{this.i=4; \\do something......}}

第三个部分就是java源代码中的构造方法中的代码,java源代码中有几个构造方法,那么class文件中就有几个初始化方法,编译器会把第一部分与第二部分分别复制到每个初始化方法的前端,然后把初始化方法对应参数的构造方法的代码复制到相应初始化方法中(这里说的复制其实应该说是编译,不过为了让你更好理解所以如此说).
那么说初始化方法如何追溯其父类的,这也关系到初始化方法的结构,初始化方法的执行顺序以及结构就如上所说,但是如果初始化方法的第一个执行指令就是调用另外一个初始化方法,这个初始化方法可能是自身类某个初始化方法,例如你的构造函数中第一句有类似this(...)这种语句,那么初始化方法就会调用自身类的指定构造方法;如果你的构造方法中没有指定构造方法调用,那么初始化方法会默认调用父类无参数初始化方法,如果你的构造方法的第一句为super(....), 那么初始化方法会调用父类的指定初始化方法。这种调用过程会递归进行调用,直到这个类是java.lang.Object类。
调用初始化方法并不代表会生成对象,你的java代码中出现new关键字加上构造方法的调用,只会生成一个对象,其父类对象不会生成,所以调用父类为抽象类的构造方法完全是合理的。而且初始化方法对于虚拟机来说只是一个名称叫做"<init>"的普通方法,区别只是生成对象以后调用而已(sun 的jdk私有包中有绕过构造方法生成对象的方式,可以证明之上说法,具体如何我这里不陈述)。

2. 抽象类中的构造方法其实是用来给继承的子类来用的,因为构造方法相当于初始化方法,当子类调用构造方法时必须调用父类构造方法,所以你可以在子类产生对象时抽象类中按需求初始化抽象类中的字段以及执行一些初始化代码。其实并不是一定要生成某个类的实例才调用构造方法,子类也需要调用父类构造方法。而生成实例也并不一定会调用构造方法,在某些特殊实现中或者特殊情况下,生成实例不会调用构造方法。而调用了构造方法也不一定就生成了一个实例,但是那一定是一个实例调用的,就像一个普通的实例方法一样。
分享到:
评论

相关推荐

    面向对象的思考过程(英文版).zip

    6. **构造器**:构造器是类中特殊的方法,用于初始化新创建的对象。它们通常与类名相同,无返回类型,用于设置对象的初始状态。 7. **访问控制**:访问控制是通过访问修饰符来限制类、方法和变量的可见性,确保代码...

    程序设计4PPT课件.pptx

    这些变量会被按照Java的默认初始化规则进行初始化。 2. **构造方法参数绑定**:然后,构造方法的参数会被传递进来,并赋值给对应的形参。这是通过`new Person(参数列表)`来完成的。 3. **`this()`或`super()`调用*...

    类的继承和接口的扩展优秀文档.ppt

    4. **构造器**:子类可以通过`super()`调用父类的构造器,初始化继承自父类的属性。 **final和抽象类:** - `final`关键字用于修饰类、方法和变量,表示不可变或不可继承。当一个类被声明为`final`时,它不能被其他...

    java面向对象编程课后思考题答案

    7. **抽象类与接口**:抽象类不能被实例化,用于提供子类共有的属性和方法。接口则定义了一组方法签名,实现接口的类必须提供这些方法的具体实现,实现了多继承。 8. **异常处理**:Java提供了异常处理机制,通过...

    java 多态 经典讲解

    多态在构造方法中的体现较少,但重要的是理解,尽管构造方法不能被重写,它们可以被子类覆盖以初始化特定状态,从而支持更复杂的构造逻辑。 #### 六、利用继承设计:纯粹继承与扩展 继承不仅是代码重用的一种手段...

    使用Java实现面向对象编程总结

    抽象类和抽象方法是面向对象编程中的高级特性,它们主要用于定义接口规范而非具体的实现细节。抽象类的特点包括: - 用`abstract`关键字修饰。 - 不可以直接实例化。 - 可以包含抽象方法和具体方法。 抽象方法的...

    C#编程多年的学习思考

    1. **虚函数与抽象类**:C#使用`virtual`关键字声明虚方法,并使用`override`关键字重写父类的方法。抽象类使用`abstract`关键字声明,不允许实例化,但可以被继承。 2. **无修饰符的应用**:C#中有一些元素不能...

    JAVA笔记达内培训内部笔记

    4. **抽象**:抽象是对现实世界的一种模型化处理,通过定义抽象类或接口来实现。抽象类不能实例化,它主要用于定义一组公共的属性和行为供子类继承。 #### 三、类与对象 - **类**:类是对象的模板,是对象的抽象...

    C++程序设计课件:第16章 继承.ppt

    派生类的构造函数可以调用基类的构造函数,以便正确初始化基类的部分。如果未显式调用,编译器会默认调用无参数的基类构造函数。 16.4 继承与组合: 继承是一种“is-a”关系,如汽车是一种交通工具,而组合是“has-...

    The C++ Programming Language(ch 12)

    构造函数用于初始化对象,而析构函数用于释放对象占用的资源。 - **类层次结构**:通过继承,可以构建出具有层次结构的类族谱。这种层次结构有助于更好地组织代码和概念。 - **类型字段**:派生类可以拥有自己的数据...

    C 程序设计课件:第16章 继承.ppt

    - 派生类的构造函数会调用基类的构造函数来初始化基类部分。 5. **继承与组合**: - 继承是“is-a”关系,表示一个类是另一个类的类型。组合是“has-a”关系,表示一个类包含另一个类的实例作为其成员。 6. **多...

    s2-JavaOOP内部测试

    6. **抽象类与接口**:抽象类不能被实例化,用于定义共同接口和部分实现。接口则完全由抽象方法组成,用于定义行为规范,一个类可以实现多个接口。 7. **异常处理**:Java提供了异常处理机制,通过try-catch-...

    面向对象上啊啊发啊啊啊啊啊

    `abstract`关键字用于声明抽象类或抽象方法,抽象类不能被实例化,而抽象方法需要在子类中被实现。 #### 3.6 interface `interface`关键字用于声明接口,接口中只能包含抽象方法和默认方法。 ### 四、面向对象编程...

    面向对象程序设计(谭浩强) 课后习题程序

    5. **构造函数与析构函数**:构造函数用于初始化新创建的对象,而析构函数则在对象生命周期结束时执行,用于释放资源。在解决习题时,了解如何正确使用这些特殊方法至关重要。 6. **抽象类与接口**:抽象类不能被...

    <java面向对象编程>孙卫琴课后答案

    5. **构造器**:构造器是用于初始化新创建对象的特殊方法,其名称必须与类名完全相同,没有返回类型。构造器的主要任务是设置对象的初始状态。 6. **抽象类与接口**:抽象类是不能被实例化的类,通常包含抽象方法...

    Object-Oriented Programming

    初始化是对象生命周期中的一个重要环节,确保对象在其生命周期内处于正确状态。清理则是对象不再使用时释放资源的过程。本章详细介绍了ABAP中对象的初始化和清理机制。 - **继承** 继承是面向对象编程的一个核心...

    类的定义参考

    在这个例子中,`ClassName`是类的名称,`attribute1`和`attribute2`是类的属性,`__init__`是一个特殊方法(也称为构造函数),用于初始化新创建的对象。`method1`和`method2`是类的方法,它们定义了对象可以执行的...

    读 tinking in java 有 感

    继承允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码复用和功能扩展。此外,类中可以包含字段和方法,字段用于存储数据,方法用于定义对象的行为。字段可以是对象的引用,也可以是基本类型,而...

Global site tag (gtag.js) - Google Analytics