2016年7月3日 星期日

學習 JAVA

Java 跟 JavaScript 是不同的東西, 如要比擬的話, 在 linux 裏面可以看成是 c 與 c script 的差異.只不過 Java 須用 Javac compile 成 byte code 來執行, 而 JavaScript 則是在瀏覽器內執行的. 以往 Java 被認為速度慢, 現今 Android 裝置卻用 Java 作為程式開發主要語言, 可以想見它用了其他方式來改善速度慢的缺點,不得不讓人佩服. Java 與 c 的很多的語法也挺類似的. 而 Java 是一個物件導向語言, 自然有其要遵循的規則與觀念需要先建立.

java 用 javac 來翻譯成可執行碼, 副檔名必須用 java 來命名(例如 a.java), 主方法(main)必須宣告成 public static void main(String[ ] args ) {  }才可以被物件直接執行例, 如以下範例:
              //  a.java
              class Hello {
                     public static void main( String[ ] args ) {
                             System.out.println("hello");
                    }
             }
用 javac 翻譯成 byte code, 以上述 a.java 為例
            javac a.java
就會產生一個物件 Hello.class, 在 linux 底下它可以被 java (java virtual machine )來執行:
            java Hello
這樣就會印出"hello"這個字串出來.

物件(class)是 Java 程式語言中主要的型別, 用來定義成員及方法, 要存取物件的成員或方法直接用句點語法就可存取, 產生實體物件使用 new 語法:
          // b.java
           class Myclass {          // 新物件
                    int a;                 // 成員 a
                     void hello( ) {  // 一個物件方法
                            System.out.println("hello Myclass:"+a);
                     }
           }

           class Hello {
                   public static void main(String[ ]  args  ) {
                   Myclass a = new Myclass( );  // 產生 Mycalss 物件並指定給變數 a
                            a.a=3;                             // 取用 Mycalss 物件成員
                            a.hello();                        //  呼叫Mycalss 物件的方法
                  }
          }
然後後用 javac 翻譯成 byte code:
           javac b.java
會產生兩個新物件: Myclass.class 及 Hello.class, 執行 Hello.class 物件:
           java Hello
這樣就會印出"hello Myclass:3"這個字串出來.
要注意的是 a 是一個別名, 同 JavaScript 的觀念.
             class Myclass {
            int a;
                     void hello( ) {
                            System.out.println("hello Myclass:"+a);
                     }
           }

           class Hello {
                   public static void main(String[ ]  args  ) {
                   Myclass a = new Myclass( );
                    Myclass b;
                            b=a;
                            a.a=3;
                            b.hello();
                  }
          }
上例將 a 指定給 b, 其實 a 與 b 都是指著相同的物件 Myclass. a  與 b 都是 Myclass 的一個別名(alias name), 因此 a.a 被改變的話, 則 b.a 也會跟著被改變!

為了要將程式碼模組化方便管理, JAVA 提供兩個語法 package 及 import, 用 package 來宣告模組名稱, 用 import 來引入模組. 程式碼可以分散在不同檔案裡, 但使用相同的 package 來命名可以將他整合成同一模組. 而主程式檔案只要用 import 將物件引入, 不須將模組寫在主程式的檔案裡頭. 減少模組化程式被修改的風險.
型別修飾子: public, private, protected

有時候, 只是一個概念, 知道某個類別有一些相似特性, 但還不曉得如何來實現, 就可以先用關鍵字interface(類別框架, 簡稱框架)先寫個初步的程式碼來描述, 等真正運用時再加以實現(implements).例如 一支貓跟狗叫的聲音不同, 但都可歸類為動物叫聲:
                          // 只是一個框架, 不實現, 僅做宣告用
                          interface Sound {
                              void sound( );
                          }
                          // 規範並實現狗叫聲
                          class dogSound implements Sound {
                               void sound( ) {
                                           System.out.println("汪");
                                }
                          }
                          // 規範並實現貓叫聲
                          class catSound implements Sound {
                               void sound( ) {
                                           System.out.println("喵");
                               }
                          }
                          // 主要類別及程式
                          class Hello {
                                    public static void main(String[ ]  args  ) {
                                           catSound a = new catSound( );
                                           dogSound b = new dogSound( );
                                           a.sound( );
                                           b.sound( );

                                    }

                          }
interface 除了只是一個框架外, 它還可以多重繼承來自其它不同的框架, 同時框架是可以被多繼承的, 這是與一般類別相當大不同的地方. 一般類別雖只能繼承一個父類別, 但卻可以繼承多個框架. 一個抽象類別用 abstract class 來定義, 但抽象類別是不可以用 new 來產生實體的, 這是要特別注意的地方. 關鍵字extends可以用來繼承類別. 不管是抽象類別及框架或一般類別都可以繼承或是被繼承, 見以下範例:

                       // 定義類別框架
                        interface Sound {
                              void sound( ) ;
                          }
                         interface Walk {
                               void    walk( );
                          }
                        //  定義動物的抽象類別, 繼承多重框架
                       abstract class Animal implements Sound, Walk{
                               public void walk( ) {
                                         System.out.println("用四隻腳走路");
                               }                              
                       }
                        //  定義人的抽象類別, 繼承多重框架
                       abstract class Human implements Sound, Walk{
                               public void walk( ) {
                                         System.out.println("用兩隻腳走路");
                               }                              
                       }
                       // 狗繼承自動物的抽象類別, 有自己的叫聲
                       class dog extends  Animal {
                                public void sound( ) {
                                           System.out.println("汪");
                                  };
                       }
                       // 貓繼承自動物的抽象類別  但叫聲不同
                       class cat extends Animal {
                               public void sound( ) {
                                           System.out.println("喵");
                                  }
                          }
                        // 男人繼承自人的抽象類別, 且聲音也不同
                       class man extends Human {
                               public void sound( ) {
                                           System.out.println("嗨,你好");
                                  }
                       }
                     
                       class Hello {
                                    public static void main(String[ ]  args  ) {
                                           dog a = new dog( );
                                           cat b = new cat( );
                                          man c = new man( );
                                           a.sound( );
                                           a.walk( );
                                           b.sound( );
                                           b.walk( );
                                      c.sound( );
                                           c.walk( );

                                    }

                          }

要讓外部程式可以呼叫到類別(物件)內部的方法, 該方法就必須用 public 來宣告. 總結列出三種類別的差異重點:
interface (框架)可以多重繼承或被繼承, 它只是一個框架,不能寫實體程式碼.
只有 class(一般類別)可以用 new 產生實體, 不可以多重繼承一般類別, 但可以繼承多重框架. abstract class(抽象類別)不可用 new 產生實體, 除此之外與一般類別無異, 最後抽象列別或一般類別對於繼承的框架必需透過 implements 關鍵字來實現框架的實體代碼.

沒有留言: