zoukankan      html  css  js  c++  java
  • Java 面向对象—非静态代码块

    一、非静态代码块

      1、声明格式

    【修饰符】 class 类名 {
          {
                 非静态代码块
           } 
     }    

      2、非静态代码块中的代码执行时机

        (1)在"每次"创建对象的时候执行

        (2)比构造方法早

        Demo:

     1 class MyClass{
     2     private String str;
     3     
     4     public MyClass(){
     5         System.out.println("无参构造2");
     6     }
     7     public MyClass(String str){
     8         this.str = str;
     9         System.out.println("有参构造3");
    10     }
    11     
    12     {
    13         System.out.println("非静态代码块1");
    14     }
    15 }

        运行结果:先执行非静态代码中输出"非静态代码块1",然后执行无参构造方法输出"无参构造2"。

      3、实例初始化过程

        初始化过程:创建对象时,为对象进行初始化的操作

        执行顺序:

    ① 为成员变量显示赋值

    ② 执行非静态代码块

    ③ 执行构造器

        图解:

         

        Java 编译器其实,会把这三个部分的代码,合成一个叫做 <init>(【形参列表】) 实例初始化方法。

        即编译后的 .class 字节码文件中,是没有构造方法这个概念的。

        <init>(【形参列表】) 实例初始化方法的代码就是由三个部分组成:

    ① 成员变量显示赋值的代码

    ② 非静态代码中的代码

    ③ 构造器中的代码

        注意:

          1、其中的 ① 和 ② 按顺序执行,而 ③ 一定是它们当中的最后执行的。

          2、有几个构造器,就会有几个实例初始化方法。那么当创建对象的时候,调用对应的构造器时,其实执行的是对应的实例初始化方法 <init>(【...】)

    二、继承中的非静态代码块

      1、继承案例

        先来看一个没有非静态的代码块的继承关系:

        Demo:

     1 public class TestInit {
     2     public static void main(String[] args) {
     3          Father f = new Father();
     4          //执行父类的无参构造
     5 
     6          Son s = new Son();
     7          //先执行父类的无参构造,再执行子类的无参构造
     8 
     9         
    10          Son s2 = new Son("HelloWorld");
    11          //先执行父类的无参构造,再执行子类的有参构造1
    12 
    13 
    14          Son s3 = new Son("Java", 10);
    15          // 先执行父类的无参构造,再执行子类的有参构造1,然后再执行子类的有参构造2
    16 
    17     }
    18 }
    19 //父类
    20 class Father{
    21     public Father(){
    22         System.out.println("父类的无参构造");
    23     }
    24 }
    25 // 子类
    26 class Son extends Father{
    27     private String str;
    28     private int num;
    29     
    30     public Son(){
    31         //隐含了super();  子类的构造器中一定会调用父类的构造器,默认调用父类的无参构造
    32         System.out.println("子类的无参构造");
    33     }
    34     
    35     public Son(String str){
    36         //隐含了super()
    37         this.str = str;
    38         System.out.println("子类的有参构造1");
    39     }
    40     
    41     public Son(String str,int num){
    42         this(str);           //这里有this就不会有super了,然后调用本类中的构造方法
    43         this.num = num;
    44         System.out.println("子类的有参构造2");
    45     }
    46 }                

      2、含有非静态代码块的继承关系

        (1)先执行父类的实例初始化方法

          它由三部分组成:

    ① 成员变量的显示赋值

    ② 非静态代码块

    ③ 构造方法

        (2)再执行子类的实例初始化方法

          它由三部分组成:

    ① 成员变量的显示赋值

    ② 非静态代码块

    ③ 构造方法

        注意:

        ① super() 或 super(实参列表) 之前说的是调用父类的构造器,其实是调用父类对应的实例初始化方法

        ② super() 或 super(实参列表) 之前说的是在子类构造器的首行,其实是在子类实例初始化方法的首行,所以会先完成父类的初始化,再进行子类的初始化。

        Demo:

     1 public class TestInit {
     2     public static void main(String[] args) {
     3         Fu f = new Fu();   //312
     4         System.out.println("==========");
     5         Zi z = new Zi();    //312645
     6     }
     7 }
     8 
     9 
    10 class Fu{
    11     private String strFu = assignFu();
    12     {
    13         System.out.println("(1)父类的非静态代码块");
    14     }
    15     public Fu(){
    16         System.out.println("(2)父类的无参构造");
    17     }
    18     public String assignFu(){
    19         System.out.println("(3)父类的assignFu()");
    20         return "fu";
    21     }
    22 }
    23 class Zi extends Fu{
    24     private String strZi = assignZi();
    25     {
    26         System.out.println("(4)子类的非静态代码块");
    27     }
    28     public Zi(){
    29         //super()  ==>调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
    30         System.out.println("(5)子类的无参构造");
    31     }
    32     
    33     public  String assignZi(){
    34         System.out.println("(6)子类的assignZi()");
    35         return "zi";
    36     }
    37 }

       运行结果:

         

          图解:

      

      3、含有非静态代码块的重写继承关系

        Demo:

     1 public class TestInit {
     2     public static void main(String[] args) {
     3         Ba b = new Ba();    // 312
     4         System.out.println("============");
     5         Er r = new Er();      //612645,因为子类重写了assign()
     6         
     7     }
     8 }
     9 class Ba{
    10     private String str = assign();
    11     {
    12         System.out.println("(1)父类的非静态代码块");
    13     }
    14     public Ba(){
    15         System.out.println("(2)父类的无参构造");
    16     }
    17     public String assign(){
    18         System.out.println("(3)父类的assign()");
    19         return "ba";
    20     }
    21 }
    22 class Er extends Ba{
    23     private String str = assign();
    24     {
    25         System.out.println("(4)子类的非静态代码块");
    26     }
    27     public Er(){
    28         //super()  ==>调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
    29         System.out.println("(5)子类的无参构造");
    30     }
    31     
    32     public String assign(){
    33         System.out.println("(6)子类的assign()");
    34         return "er";
    35     }
    36 }

      运行结果:

      

      图解:

       注意:this在构造器中,在实例化初始化方法中,代表的是正在创建的对象,当创建子类对象时,因为子类重写的 assign(),那么执行是子类重写的 assign() 方法。

       

  • 相关阅读:
    03_ if 练习 _ little2big
    uva 11275 3D Triangles
    uva 12296 Pieces and Discs
    uvalive 3218 Find the Border
    uvalive 2797 Monster Trap
    uvalive 4992 Jungle Outpost
    uva 2218 Triathlon
    uvalive 3890 Most Distant Point from the Sea
    uvalive 4728 Squares
    uva 10256 The Great Divide
  • 原文地址:https://www.cnblogs.com/niujifei/p/11885737.html
Copyright © 2011-2022 走看看