Java 面向對象編程之構造方法、構造代碼塊(1)

Java 面向對象編程之構造方法、構造代碼塊html

面向對象編程是咱們認識世界,創造事物的一種新的思惟,其實就抓大放小,將全部共性的事物進行封裝的過程。編程人員在進行流程做業時,能夠方便的進行復用。java

站在面向對象的角度看問題,編程就是對象的動做的調用;站在面向過程的角度,編程就是動做的執行者。「把大象裝進冰箱」就能夠完美的解釋面向對象和麪向過程的區別。編程

就如同一個 「Baby」 對象創建以後,那麼生孩子的過程就會變得很簡單:安全

public class Baby {                 // 定義一個Baby類
    Long IDcard;
    String name;
    public void eat()
    {
        System.out.println(name+"...eat...");
    }
    public void run(){
        System.out.println(name+"...run...");
    }
}

但是不是全部生下來的孩子都是同樣的,他們具備不一樣的身份證號碼,不一樣的名字。jvm

因此,new一個對象很簡單,可是要考慮初始化對象,並給予不一樣的區別就要對這個類進行構造方法。函數

構造方法(構造函數):給對象進行統一的初始化。如代碼:測試

public class Baby {
    Long IDcard;
    String name;
    public void eat()
    {
        System.out.println(name+"...eat...");
    }
    public void run(){
        System.out.println(name+"...run...");
    }
    
    public Baby()                             // 無參數的構造函數
    {
        System.out.println("my name is "+name+";my idcard is :"+IDcard);
    }
    
    public Baby(Long IDcard,String name)      // 有參數的構造函數
    {
        System.out.println("my name is "+name+";my idcard is :"+IDcard);
    }  
}
  • 調用無參數的:  Baby baby = new Baby();   
  • 運行結果       :my name is null;my idcard is :null
  • 調用有參數的:Baby baby2= new Baby(23L,"Ben");
  • 運行結果       :my name is Ben;my idcard is :23

 

構造函數要注意的細節:


    1. 構造函數是沒有返回值類型的。
    2. 構造函數的函數名必需要與類名一致
    3. 構造函數並非由咱們手動調用的,而是在建立對應的對象時,jvm就會主動調用到對應的構造函數
    4. 若是一個類沒有顯式的寫上一個構造方法時,那麼java編譯器會爲該類添加一個無參的構造函數的。
    5. 若是一個類已經顯式的寫上一個構造方法時,那麼java編譯器則不會再爲該類添加 一個無參的構造方法。
    6. 構造函數是能夠在一個類中以函數重載的形式存在多個的spa

 

構造函數與普通函數的區別:    


    1. 返回值類型的區別:htm

  • 構造函數是沒有返回值類型;
  • 普通函數是有返回值類型的,即便函數沒有返回值,返回值類型也要寫上void。

    2. 函數名的區別:對象

  • 構造函數的函數名必需要與類名一致;
  • 普通函數的函數名只要符合標識符的命名規則便可。

    3. 調用方式的區別:

  • 構造函數是 在建立對象的時候由jvm調用的。
  • 普通函數是由咱們使用對象調用的,一個對象能夠對象屢次普通的函數,

    4. 做用上的區別:

  • 構造函數的做用用於初始化一個對象。
  • 普通函數是用於描述一類事物的公共行爲的。

 

Java中靜態代碼塊、構造代碼塊、構造函數、普通代碼塊

 在Java中,靜態代碼塊、構造代碼塊、構造函數、普通代碼塊的執行順序是一個筆試的考點,經過這篇文章但願能完全瞭解它們之間的執行順序。

(1)靜態代碼塊:

代碼結構:在java類中使用static關鍵字和{}聲明的代碼塊,通常是類中才有這樣的結構,方法中不存在。

public class CodeBlock {
    static{
        System.out.println("靜態代碼塊");
    }
}

執行時機:靜態代碼塊在類被加載的時候就運行了,並且只運行一次,而且優先於各類代碼塊以及構造函數。若是一個類中有多個靜態代碼塊,會按照書寫順序依次執行。後面在比較的時候會經過具體實例來證實。

靜態代碼塊的做用:通常狀況下,若是有些代碼須要在項目啓動的時候就執行,這時候就須要靜態代碼塊。好比一個項目啓動須要加載的不少配置文件等資源,咱們就能夠都放入靜態代碼塊中。

靜態代碼塊不能存在任何方法體中:

       靜態代碼塊是在類加載的時候就要運行了。咱們分狀況討論:

  對於普通方法,因爲普通方法是經過加載類,而後new出實例化對象,經過對象才能運行這個方法,而靜態代碼塊只須要加載類以後就能運行了。

  對於靜態方法,在類加載的時候,靜態方法也已經加載了,可是咱們必需要經過類名或者對象名才能訪問,也就是說相比於靜態代碼塊,靜態代碼塊是主動運行的,而靜態方法是被動運行的。

  不論是哪一種方法,咱們須要明確靜態代碼塊的存在在類加載的時候就自動運行了,而放在不論是普通方法仍是靜態方法中,都是不能自動運行的。

靜態代碼塊不能訪問普通變量:普通變量只能經過對象來調用,是不能放在靜態代碼塊中的。

(2)構造代碼塊:

代碼結構:在java類中使用{}聲明的代碼塊(和靜態代碼塊的區別是少了static關鍵字):

public class CodeBlock {
    static{
        System.out.println("靜態代碼塊");
    }
    {
        System.out.println("構造代碼塊");
    }
}

執行時機:構造代碼塊在建立對象時被調用,每次建立對象都會調用一次,可是優先於構造函數執行。須要注意的是,聽名字咱們就知道,構造代碼塊不是優先於構造函數執行,而是依託於構造函數,也就是說,若是你不實例化對象,構造代碼塊是不會執行的。怎麼理解呢?咱們看看下面這段代碼:

public class CodeBlock {
    {
        System.out.println("構造代碼塊");
    }
     
    public CodeBlock(){
        System.out.println("無參構造函數");
    }
    public CodeBlock(String str){
        System.out.println("有參構造函數");
    }
}

若是存在多個構造代碼塊,則執行順序按照書寫順序依次執行。

構造代碼塊的做用:

        和構造函數的做用相似,都能對對象進行初始化,而且只要建立一個對象,構造代碼塊都會執行一次。可是反過來,構造函數則不必定每一個對象創建時都執行(多個構造函數狀況下,創建對象時傳入的參數不一樣則初始化使用對應的構造函數)。

  利用每次建立對象的時候都會提早調用一次構造代碼塊特性,咱們能夠作諸如統計建立對象的次數等功能。

(3)構造函數:

       1.構造函數的命名必須和類名徹底相同。在java中普通函數能夠和構造函數同名,可是必須帶有返回值;

  2.構造函數的功能主要用於在類的對象建立時定義初始化的狀態。它沒有返回值,也不能用void來修飾。這就保證了它不只什麼也不用自動返回,並且根本不能有任何選擇。而其餘方法都有返回值,即便是void返回值。儘管方法體自己不會自動返回什麼,但仍然可讓它返回一些東西,而這些東西多是不安全的;

  3.構造函數不能被直接調用,必須經過new運算符在建立對象時纔會自動調用;而通常的方法是在程序執行到它的時候被調用的;

  4.當定義一個類的時候,一般狀況下都會顯示該類的構造函數,並在函數中指定初始化的工做也可省略,不過Java編譯器會提供一個默認的構造函數.此默認構造函數是不帶參數的。而通常的方法不存在這一特色;

(4)普函數:

        普通代碼塊和構造代碼塊的區別是,構造代碼塊是在類中定義的,而普通代碼塊是在方法體中定義的。且普通代碼塊的執行順序和書寫順序一致。

public void sayHello(){
    {
        System.out.println("普通代碼塊");
    }
}

(5)執行順序:

        靜態代碼塊>構造代碼塊>構造函數>普通代碼塊 

public class CodeBlock {
    static{
        System.out.println("靜態代碼塊");
    }
    {
        System.out.println("構造代碼塊");
    }
    public CodeBlock(){
        System.out.println("無參構造函數");
    }
     
    public void sayHello(){
        {
            System.out.println("普通代碼塊");
        }
    }
     
    public static void main(String[] args) {
        System.out.println("執行了main方法");
         
        new CodeBlock().sayHello();;
        System.out.println("---------------");
        new CodeBlock().sayHello();;
    }
}

(6)父類和子類的執行順序:

       對象的初始化順序:

  首先執行父類靜態的內容,父類靜態的內容執行完畢後,接着去執行子類的靜態的內容,當子類的靜態內容執行完畢以後,再去看父類有沒有構造代碼塊,若是有就執行父類的構造代碼塊,父類的構造代碼塊執行完畢,接着執行父類的構造方法;父類的構造方法執行完畢以後,它接着去看子類有沒有構造代碼塊,若是有就執行子類的構造代碼塊。子類的構造代碼塊執行完畢再去執行子類的構造方法。

  總之一句話,靜態代碼塊內容先執行,接着執行父類構造代碼塊和構造方法,而後執行子類構造代碼塊和構造方法。

       父類:SuperClass.java

public class SuperClass {
    static{
        System.out.println("父類靜態代碼塊");
    }
    {
        System.out.println("父類構造代碼塊");
    }
    public SuperClass(){
        System.out.println("父類構造函數");
    }
}

        子類:SubClass.java

public class SubClass extends SuperClass{
    static{
        System.out.println("子類靜態代碼塊");
    }  
    {
        System.out.println("子類構造代碼塊");
    } 
    public SubClass(){
        System.out.println("子類構造函數");
    }  
}

           測試:

public static void main(String[] args) {
    SubClass sb = new SubClass();
    System.out.println("------------");
    SubClass sb1 = new SubClass();
}

相關文章
相關標籤/搜索