java继承&子父类成员域加载及执行过程

原创 2015年11月17日 20:15:30

前段时间偶然看到一篇文章,关于java继承的,讲其加载顺序,然后我就看蒙了,虽然接触过不少时间java,用起来因为编译器的存在没什么语法问题,但真正用notepad++时,发现细节真的很重要,下面看测试时用的例子。

package one;
import java.util.*;

public class Test extends Parent {
    static int c=getInt(1);//2初始化子类静态成员域 
    int d=getInt(2);//6初始化子类非静态成员域
    private String name;
    private int age;
    public Test() {
        name="Tom";
        age=20;//此时可以给成员域赋值,这是在成员域已经进行了默认的赋值之后才进行的操作,也就是说不赋值也不会有编译错误。
        System.out.println("7 子类构造函数执行。注意,父类子类成员初始化构造函数执行生成实例后,new操作终于算完成。");
    }
    public static void main(String[] args) {
         System.out.println("3 执行与对象实例化无关的操作。");//3执行与对象实例化无关的操作。
        Test t = new Test();
        // 7父类子类成员初始化构造函数执行生成实例后,new操作终于算完成。
        System.out.println("8 执行剩余无需生成实例的代码。此时注意,t是子类实例,该类中没有num成员,而此时编译无错误,说明子类t同时是父类的实例  " + t.age+"  "+t.num);
        // 8执行剩余无需生成实例的代码。此时注意,t是子类实例,该类中没有num成员,而此时编译无错误,说明子类t同时是父类的实例
        t.c();
        // 9子类对象执行c方法,虽然父类中同样有c方法,但不会被执行。 

        System.out.print("\n\n\n下来来看另一个实例:在子类中new父类实例,看看执行的步骤:\n");
        Parent p=new Parent();
        p.c();
        //用父类实例来调用c,看执行的到底是子类还是父类中的方法。

            //System.out.println(" "+p.getInt(1));
            //尝试用p来调用test类中的方法getInt,编译器会报错:找不到符号:类型为Parent的变量P,一个错误。也就是说p为Parent的实例,但不是子类的实例。

        System.out.print("\n\n\n下来来看另一个实例:在子类中new子类实例,然后赋值给父类对象,也就是向上转型,看看执行的步骤:\n");
        Parent pa=new Test();
        //此时编译正常通过,向上转型没有丝毫问题,不需要强制。
    }

    @Override//注:@Override只是提醒自己这是个与父类同名同参的函数,并无实际作用,切不要被误导。
    public void c(){
        System.out.println("9 子类对象执行c方法,虽然父类中同样有c方法,但不会被执行。");
    }

    public static int getInt(int i){
        System.out.println((i==1)?"2 初始化子类静态成员域":"6 初始化子类非静态成员域");
        return i;
    }
}
class Parent {
    static int K=1;
    int sum=test(3);
    int num = test(2);//4需要生成子类实例时,先初始化父类非静态成员域,即便没有使用到的成员也会被初始化,这可以看出,是按照顺序初始化的,
    static int sam=test(K);//1从子类main方法入口进入后,最先初始化父类静态成员域。“在类被加载的同时会将静态成员进行加载。而且看我这里调用的是K的值,如果只是加载了静态成员而没有被赋值的话,那K应该为0,然而此时K为1”
    public Parent() {
        System.out.println("5 执行父类构造函数,生成父类实例对象。");
        //5执行父类构造函数,生成父类实例对象。
    }
    public static int test(int i) {
        switch(i){
            case 1:{
                System.out.println("1 从子类main方法入口进入后,最先初始化父类静态成员域sam");
                break;
            }
            case 2:{
                System.out.println("4 先初始化父类非静态成员域num");
                break;
            }
            case 3:{
                System.out.println("4 先初始化父类非静态成员域sum");
                break;
            }
        }
        return i;
    }
    public void c(){
        System.out.println("被子类覆盖了的父类方法,子类对象不能直接访问 ");
    }
}

我知道大家最不喜欢的就是看代码,因为它远不如文字来的形象直观,并且不能跳跃,其实我也不喜欢,所以,可以对照着输出来看源码:
这里写图片描述
为了我以后方便查看,我把print的内容都换了,这样就直观多了,注释上有序号,对照着输出看,如果真是懒得看,那直接看从中得出的结论。(注:源码可执行,有不明的地方可以将其他部分注释掉单独看结果。)

如果子类main方法中不执行new操作,那么执行结果为:
这里写图片描述
可以看到只有父类和子类的静态成员域得到初始化,非静态成员域没有得到任何初始化,并且可以试着使创建父类对象,可以得出:
1、要创建子类对象时,会自动先创建父类的实例对象。
2、在类被加载的同时会将静态成员进行加载并得到初始化且能赋值。
3、在类的实例被创建时,非静态成员才会得到初始化,然后调用类的构造函数生成实例。
4、子类实例同时是父类实例,可以调用父类方法,成员也是可以调用的(如例子中子类无num,但可以使用),如果父类子类有相同的方法或属性,优先调用子类中的(使用super可以调用父类中方法及属性)。
5、父类的实例不是子类的实例。不能调用子类方法。

后面两个模块之所以没有第一到第三步,是因为我没有注释完全,不影响查看。代码中注字部分是要点。

版权声明:本文为博主原创文章,未经博主允许不得转载。

继承原则与子父类初始化过程,类成员访问权限,普通类与抽象类,throwble类,重写与重载,string对象修改,i=i++;

Public>protected>default>private 以上是类成员访问权限及权限大小 2.继承原则和继承时初始化过程 子类继承父类的成员变量 子类继承父类除构造方法以外的成...
  • bird_tp
  • bird_tp
  • 2017年11月20日 22:18
  • 22

Java 继承之子父类中的成员变量和函数

成员变量: 先看这样一段代码: //父类。 class Fu { int num = 3; } class Zi extends Fu { int num = 4; void show() ...

Java重修之路(八)面向对象之继承,子父类中变量、函数、构造函数的特点,子类实例化过程。

继承继承就是子类继承父类的特征和行为,使得子类具有父类的各种属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。 提高了代码的复用性 让类与类之间产生关系,有了多态的特性。 ...

【继承】----子父类成员变量--内存简单图解

继承中子父类成员变量的内存简单图解 class Fu { int num=21; } //写一个子类 class Zi extends Fu { int num...

继承—子父类中成员函数的特点-覆盖

继承—子父类中成员函数的特点-覆盖 一、成员函数 1. 子类如何查找成员函数 ·当子类和父类中出现的成员函数相同(返回值类型,函数名相同,参数列表相同)时,会运行子类的函数;这种现象,成为覆盖操...

继承——子父类出现后,类成员的特点

子父类出现后,类成员的特点 类中成员: 1.变量  如果子类中出现非私有的同名成员变量时, 子类要访问本类中的变量,用this, 子类要访问父类中的同名变量,用super super的使用和this...

黑马程序员 第16天 继承 子父类出现后,类成员的特点 子类的实例化进程

---------------------- ASP.Net+Unity开发、<a href="http://edu.csdn.net"target="blank">.Net培训、期待与您交流!...

JAVA子父类中构造函数的特点-子类实例化过程

//仅作为学习笔记 /* 子父类中的构造函数 在对子类对象进行初始化时,父类的构造函数也会运行 那是因为子类的构造函数默认的第一行有一句隐式的语句super() super():会访问...

java面向对象-子父类中构造函数的特点-子类实例化过程super

/* 3,子父类中的构造函数 在对子类对象进行初始化时,父类的构造函数也会运行 那是因为子类的构造函数默认第一行隐式的语句super(); super():会访问父...

Java子父类中的构造函数实例化过程

其实我们发现子类继承父类操作很简单,如果要是去深入的研究下会发现,实例化过程并非是我们看到的那样,我们就以代码举例来说明;问大家,以下代码执行会输出什么呢?package com.oop;/** *...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java继承&子父类成员域加载及执行过程
举报原因:
原因补充:

(最多只允许输入30个字)