網頁

2013年3月25日 星期一

Java Programming Introduction 03: class instantiation


class 是一個虛擬的東西, 要使用它的時候, 要先對它配置記憶體, 並且把它建構起來. 用說的還是比較沒有感覺, 先看一下 code.

1. Instantiation:


example 1:


public class HelloWorld {
        public static void main(String[] args) {

                System.out.println("I'm main");
                HelloWorld hello_world = new HelloWorld();
                hello_world.printMesage();  
        }

        public HelloWorld(){
                System.out.println("I'm constructor");  
        }

        public void printMesage(){
                System.out.println("I'm member");  
        }
}

 
執行的結果如下:

java HelloWorld

I'm main
I'm constructor
I'm member

這邊再說明一下這個執行的順序

step 1, java 載入 HelloWorld.class 這個檔案, 並且在其中找到 HelloWorld 這個同名的 class, 並且在其中找到 main 這個 function, 並且執行它.

step 2, main 這個 function , new 這個 operator 實體化 HelloWorld 這個 class, 配置計憶體, 如果有的話, 呼叫它的建構元 (constructor). 所以這一行程式, 會看起來是這個樣子:

HelloWorld hello_world = new HelloWorld();
class 的名稱後的小刮號, 應該視為 constructor, 而不是 function.

step 3, constructor 被呼叫. constructor 的特別限制是不能有傳回值. 如果 constructor 的執行中遇到問題, 則可以丟出 exception, 由呼叫端去處理.

step 4, 呼叫 printMessage .

到這邊不知道有沒有人覺得很奇怪, HelloWorld constructor 被執行前, HelloWord main 已經被呼叫. 而且是在 HelloWord function 裡面, 去建構自己. 或者, 看看下個例子:

example 2:


public class HelloWorld {

        public static void main(String[] args) {

                System.out.println("I'm main");
                HelloWorld.preConstructor();
                HelloWorld hello_world = new HelloWorld();
                hello_world.printMesage();  
        }

        public HelloWorld(){
                System.out.println("I'm constructor");  
        }

        public void printMesage(){
                System.out.println("I'm member");  
        }

        public static void preConstructor(){
                System.out.println("I'm called before constructor");
        }
}

 

執行的結果如下:

java HelloWorld

I'm main
I'm called before constructor
I'm constructor
I'm member
 

關鍵就是 static 這個 key word.
 

2. static


有一個簡單的方法來瞭解 static. class 可以分解成虛部和實部. static 定義的是實部, 因為是實部, 所以它在被定義之就存在, 不能存取虛部的 member, 同時它也是唯一的.

虛部的部份, 它必需要被實體化, 所以它可以有很多分身.

以下的例子, 說明 static 的唯一性:

public class HelloWorld{

        static String message = "HelloWorld";

        public static void main(String[] args) {

                System.out.println(HelloWorld.message);
 
                HelloWorld hello_1 = new HelloWorld("Hello one");
                System.out.println(HelloWorld.message);                     
                System.out.println(hello_1.message);                   

                HelloWorld hello_2 = new HelloWorld("Hello 2two");
                System.out.println(HelloWorld.message);     
                System.out.println(hello_1.message);
                System.out.println(hello_2.message);           
        }
       

        public HelloWorld(String text){
                message = text;
        }
}

執行的結果如下:

HelloWorld

Hello one

Hello one

Hello two

Hello two

Hello two

從結果可以看到, HelloWorld 的這個 static message, 不需要實體化就可以引用, 它的值是 " HelloWorld". 接下來我們實體化成 hello_1, 並變更 message 的值為 "Hello one", 結果不管是從 class 的名稱 (HelloWorld) 引用, 或是從變數 hello_1 引用, 它的值都是 "Hello one". 接著我們再實體化 hello_2, 連變數 hello_1 message 都變成 "Hello 2two", 唯一合理的解釋, 就是這個 static String message 只有一個, 不管 HelloWord 類別有沒有被實體化, 或是實體化了多少個分身, 就只有這一個.

 

 

沒有留言:

張貼留言

請提供您寶貴的意見