Java中创建一个子类对象会不会创建父类对象由子类实例化

创建一个子类对象会不会创建父类对象?
来源:博客园
创建一个子类对象会不会创建父类对象?不会,只创建了一个子类对象,但是往父类对象的构造方法里传了子类对象的地址;给子类对象初始化的时候,调用了父类的构造方法。证明:class A{
public A(){
System.out.println("A=="+this.hashCode());
}}class B extends A{
public B(){
System.out.println("B=="+this.hashCode());
}}public class test{
public static void main(String[] args){
A test=new B();
}}结果:A==B==如果子类对象创建的同时也创建了一个父类对象,那么父类和子类构造方法中this的hashcode(内存地址)会不一样,但结果相同。
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动java创建一个子类对象是会调用父类的构造方法会不会创建父类
java创建一个子类对象是会调用父类的构造方法,会不会同时创建父类的对象。
09-09-16 &匿名提问
貌似是多态性的问题基类指针即使接受子类的地址,也只能访问基类的属性和方法除非这个基类有一个虚函数,并且在子类重载,那么此时就调用子类的方法
请登录后再发表评论!
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    public class Test{ private int i=0;//初始化第一部分 //以下大括号内为初始化第二部分 { this.i=4; \\do something...... } }第三个部分就是java源代码中的构造方法中的代码,java源代码中有几个构造方法,那么class文件中就有几个初始化方法,编译器会把第一部分与第二部分分别复制到每个初始化方法的前端,然后把初始化方法对应参数的构造方法的代码复制到相应初始化方法中(这里说的复制其实应该说是编译,不过为了让你更好理解所以如此说).那么说初始化方法如何追述其父类的,这也关系到初始化方法的结构,初始化方法的执行顺序以及结构就如上所说,但是每个初始化方法的第一个执行指令就是调用另外一个初始化方法,这个初始化方法可能是自身类某个初始化方法,例如你的构造函数中第一句有类似this(...)这种语句,那么初始化方法就会调用自身类的指定构造方法;如果你的构造方法中没有指定构造方法调用,那么初始化方法会默认调用父类无参数初始化方法,如果你的子类第一句为 super(....),那么初始化方法会调用父类指定初始化方法。这种调用过程会递归进行调用,直到这个类是java.lang.Object类。调用初始化方法并不代表会生成对象,你的java代码中出现new关键字加上构造方法的调用,只会生成一个对象,其父类对象不会生成,所以调用父类为抽象类的构造方法完全是合理的。而且初始化方法对于虚拟机来说只是一个名称叫做& &init&&的普通方法,区别只是生成对象以后调用而已(sun 的jdk私有包中有绕过构造方法生成对象的方式,可以证明之上说法,具体如何我这里不陈述)。然后回答你的第二个问题,抽象类中的构造方法其实是用来给继承的子类来用的,因为构造方法相当于初始化方法,当子类调用构造方法时必须调用父类构造方法,所以你可以在子类产生对象时抽象类中按需求初始化抽象类中的字段以及执行一些初始化代码。其实并不是一定要生成某个类的实例才调用构造方法,子类也需要调用父类构造方法。而生成实例也并不一定会调用构造方法,在某些特殊实现中或者特殊情况下,生成实例不会调用构造方法。而调用了构造方法也不一定就生成了一个实例,但是那一定是一个实例调用的,就像一个普通的实例方法一样。
请登录后再发表评论!Java中创建子类对象的执行流程分析--嵌入式学院(华清远见旗下品牌)
Java中创建子类对象的执行流程分析
作者:冯老师,讲师。
一、影响创建子类对象的几个因素
Java中创建一个子类对象时,执行流程比较复杂,主要是由于构造器的重载、this关键字的使用、初始化块、继承及super关键字的存在。下面对这几个因素做个简单介绍。
1.方法的重载
Java中允许方法的重载,即同一个类中方法名相同,但参数个数不同或参数的类型不同。除了普通的类方法外,构造器也允许重载。且通过this关键字可以使类的构造器互相调用。
2.this关键字
在构造器中的this关键字,指该构造器所创建的新对象,在方法中的构造器关键字,指调用该方法的对象。使用this关键字,主要是下面三种场合:
在类的内部方法或构造器中引用该类的实例变量和方法;将当前对象作为参数传递给其它方法或构造器;用来调用其他的重载的构造器
3.初始化块
Java中允许类中定义初始化块,即类中的“游离块”――不属于变量声明、不属于方法、不属于构造器,但需要用{}单独括起来。不管使用哪个构造器创建对象,它都会被首先运行,然后才是构造器的主体部分被执行
二、创建子类对象的执行流程
创建一个类对象时,执行流程如下:
1.设置实例变量的值为缺省的初始值
2.调用对象的构造器,绑定构造器参数。
3.如果构造器中有this()调用,则根据this()调用的参数调用相应的重载构造器,然后,转到步骤5;否则转到步骤4。
4. 除java.lang.Object类外,调用父类的中的初始化块初始化父类的属性,然后调用父类构造器,如果在构造器中有super()调用,则根据super()中的参数调用父类中相应的构造器。
5.使用初始化程序和初始化块初始化成员。
6.执行构造器方法体中其他语句。
三、代码演示
下面通过一个例子,来演示上述流程。
1.工程结构如下:
2.工程中涉及的Java源文件如下:
1)包com.person下的父类Person的代码如下:
//------------Person.java---------------
  package com.
  public class Person {
  String name = "zhangsan";
  String gender = "male";
  int age = 200;
  public Person() {
  System.out.println("Person()");
  public Person(String newName) {
  name = newN
  System.out.println("Person(String newName)");
  System.out.println("name=" + name + " age=" + age + " gender=" + gender);
  public Person(String newName, int newAge) {
  name = newN
  age = newA
  System.out.println("Person(String newName, int newAge)");
  System.out.println("name=" + name + " age=" + age + " gender=" + gender);
  gender = "male";
  age = 50;
  System.out.println("Person initialize:" + "name=" + name + " age=" + age + " gender=" + gender);
2)包com.person下的Person的子类Teacher的代码如下:
//---------------Teacher.java---------------
  package com.
  public class Teacher extends Person{
  String department = "HR";
  int schoolage = 100;
  public Teacher() {
  System.out.println("Teacher()");
  public Teacher(String newName) {
  super(newName);
  System.out.println("Teacher(String newName)");
  public Teacher(int schoolage) {
  this.schoolage =
  System.out.println("Teacher(int schoolage)");
  public Teacher(String newName, int newAge) {
  super(newName, newAge);
  System.out.println("Teacher(String newName, int newAge)");
  public Teacher(int schoolage, String department) {
  this(schoolage);
  this.department =
  System.out.println("Teacher(int schoolage, String department)");
  age = 66;
  System.out.println("Teacher initialize:" + "name=" + name + " age=" + age + " gender=" + gender);
3)包com.person下的main函数代码如下:
//-----------Demo.java------------
  package com.
  public class Demo {
  public static void main(String[] args) {
  Teacher t1 = new Teacher();
  System.out.println("---------------------------");
  Teacher t2 = new Teacher("Tom");
  System.out.println("---------------------------");
  Teacher t3 = new Teacher(10);
  System.out.println("---------------------------");
  Teacher t4 = new Teacher("Jerry", 35);
  System.out.println("---------------------------");
  Teacher t5 = new Teacher(20, "教学部");
  System.out.println("---------------------------");
程序的执行结果如下:
Person initialize:name=zhangsan age=50 gender=male
  Person()
  Teacher initialize:name=zhangsan age=66 gender=male department=HR age=66
  Teacher()
  ---------------------------
  Person initialize:name=zhangsan age=50 gender=male
  Person(String newName)
  name=Tom age=50 gender=male
  Teacher initialize:name=Tom age=66 gender=male department=HR age=66
  Teacher(String newName)
  ---------------------------
  Person initialize:name=zhangsan age=50 gender=male
  Person()
  Teacher initialize:name=zhangsan age=66 gender=male department=HR age=66
  Teacher(int schoolage)
  ---------------------------
  Person initialize:name=zhangsan age=50 gender=male
  Person(String newName, int newAge)
  name=Jerry age=35 gender=male
  Teacher initialize:name=Jerry age=66 gender=male department=HR age=66
  Teacher(String newName, int newAge)
  ---------------------------
  Person initialize:name=zhangsan age=50 gender=male
  Person()
  Teacher initialize:name=zhangsan age=66 gender=male department=HR age=66
  Teacher(int schoolage)
  Teacher(int schoolage, String department)
  ---------------------------
四、总结分析
通过观察上面的执行结果,可以看出,在创建子类对象时,一定会先设置父类实例变量的值为缺省的初始值 ,再调用父类的初始化块,然后是调用父类一个匹配构造器。接下来是,调用子类实例变量的值为缺省初始值,调用子类的初始化块,最好是子类的构造器。}

我要回帖

更多关于 父类对象由子类实例化 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信