我的Thinking in Java學習筆記(九)

來源:互聯網
上載者:User

第五章       隱藏實現細目
  首先考慮oop的一個重要思想--讓變動的東西和不變動的事物彼此分開。
  java庫的程式員在編寫庫的時候最需要考慮到的就是,一旦他們改變類中的某個函數或者是成員變數,讓已經使用前一版本庫的程式不會受到變動的影響。庫的編寫者無法知道程式員調用用了庫中那些函數和變數,因而無法修改庫的成員,於是為瞭解決這樣的問題,java中出現了存取控制符,其作用就是告訴程式員,那些是可用的,那些是停用,而java中的存取控制符是受package(包)的影響的,因此,在學習存取控制符以前,先要學習好包。
  package:程式庫單元
    現在大家想象一下這種情況,假如你現在本地開發了一套java程式,現在把他投入使用,當你把程式放到伺服器上的時候,也許你會發現,伺服器上的原有的class和你現在程式中的class重名了!怎麼解決呢?這個時候就需要java中的命名空間了。正是因為有了命名空間,使得名稱相同的class各自存活在各自的相對領域中,互不干擾,當你需要調用不同命名空間內的class時,使用import關鍵字,例如:調用整個程式庫import java.util.*;這樣就是在調用一個包,如果你想調用其中的一個類,這樣import java.util.math;
    如何設定自己的包?使用package xxx ;放在程式的最前面,就是把該程式收錄到xxx包中,使用的時候,只要import xxx就可以了。關鍵字import和package提供的是,無論多少人撰寫class,永遠不會發生命名衝突!
    獨一無二的package命名
      package應該把所有隸屬於同一個package的class放置在同一個目錄中,或者使用jar。那麼現在又出現2個問題:如何產生獨一無二的package名,並且如何找出深藏在檔案目錄中class。我們一般使用反轉的國際網域名稱來保障問題1的正確解決,我的網域名稱是blog.csdn.com/maoerzuozuo,於是我使用maoerzuozuo.com.csdn.blog來命名包,這樣我就能產生和其他人不重複的package名稱(除非他把我的東西搶先使用)。第2個問題通過環境變數中的classpath解決,classpath含有一個或者多個目錄,每個目錄看成class檔案的尋找起點,把你的包名稱轉換成磁碟目錄進行尋找
      package maoerzuozuo.com.csdn.blog.test;
      public class demo
      {
       public demo()
       {
        System.out.println("maoerzuozuo.com.csdn.blog.test.demo");
       }
      }
      調用
      import maoerzuozuo.com.csdn.blog.test.*;
      public class test
      {
       public static void main(String args[])
       {
        demo d= new demo();
       }
      }
      我們把2檔案儲存體在f:/maoerzuozuo/com/csdn/blog/test/下,接著我們調用他,並且設定環境變數classpath=.;f:/; 於是程式正常運行,編譯器能找到我調用的包,並且能正常運行。注意:你需要調用的class必須是public的!
      衝突
      假如我調用了2個包,但是2個包中都有test類,當我執行個體化test類時候,你必須告訴編譯器你執行個體化的是哪個包中的class,否則就會引起衝突
      例如  java.util.Date d= new java.util.Date();
    自定一個程式庫
      現在,我們可以定義屬於自己的程式庫,方便自己的使用,這裡我們定義一個輸出類,用來方便我們程式使用.我們現在來寫一個顯示類
      package maoerzuozuo.com.csdn.blog.test;
      public class show
      {
       public static void go(String s)
       {
        System.out.println(s);
       }
      }
      我們把他存放在F:/maoerzuozuo/com/csdn/blog/test 下,並且在環境變數的下classpath做好指向,現在來使用
      import maoerzuozuo.com.csdn.blog.test.show;
      class test
      {
       public static void main(String args[])
       {
        show.go("hello");
       }
      }
      但是請注意,當我們調用show.go(123);的時候,go()函數沒辦法像System.out.println();一樣把int自動進行轉化為string
    使用package的一些忠告
      當你是使用package的時候,其實你也就是間接的指定了實際的系統目錄結構,因此,你的class必須位於這個目錄之中,並且系統會從classpath開始,查詢到該目錄。
    
   java存取權限控制詞
    java中,對類、函數、成員資料都會有存取控制符,他們依次為public 、private、protected 和 friendly(無存取控制符)4種,我記得我當時培訓的時候,我的老師告訴我"public 是公用的,private是私房錢 protected是大熊貓"
    friendly(友好的)
      當在類、函數、成員資料前不寫任何存取控制符的時候,就是friendly,他的意義就是在同一個包中,所有的class都可以訪問,或者當你沒有定義任何的包的時候,只要在同一個目錄內的檔案也是可以互相訪問的,編譯器會視他們為一個包,但是對於包外的class形同private,也可以稱做package存取權限
    public (公用的)
      關鍵字public代表任何人都可以訪問他
    private(私房錢)
      先想想私房錢的概念,私房錢只所以這麼叫,是因為這個錢只有本人自己才能使用。所以private代表的意思就是說除了class本身,沒有誰再能訪問他了。private充分體現了封裝性
    protected(大熊貓)
      大熊貓是受到保護的,並且他的子女因為繼承大熊貓的關係也是受到保護的,所以protected的意義在於允許衍生類別訪問基類的成員,而基類的包中的其他類也是可以訪問的(friendly)
   interface(介面) and implemention(實現)
    實現細節的隱藏通常使用存取控制符來實現,他可以把class內的資料根據不同的需要封裝起來,讓特定的人訪問,建立不同的訪問界限
    通常我們在2種情況下需要使用存取控制符
      1、告訴二次開發的程式員,那些是可用的,那些是停用,從而當我們更改 相關資料時,不會影響到其他的人原有的程式。
      2、將介面和實現分離,一般用戶端程式員使用的是該類的介面,而具體的實現過程沒有必要讓程式員知道,我們可以將他封裝起來。這樣,我們可以把介面聲明為公用的,而內部的實現過程可以根據實際的需要,聲明為受保護的或者是私人的。
   class 的存取權限
     把關鍵字放在class之前,可以聲明該class的存取權限,需要注意的是
     1、每個檔案中只能有一個public類用來表現單一的介面,檔案內可以存在為了支援public類而存在的friendly類;
     2、public類的名稱必須和所在檔案的檔案名稱相同,包括大小寫也要一致;
     3、當檔案內不包含任何public類的時候,你可以使用任意名稱做為檔案名稱;
     4、class的存取控制符不能是private或者是protected的,只能是friendly和public的,如果你希望別人無法產生對象,你只要把建構函式聲明為private的就可以了
   習題解答
     1、撰寫一個程式,在其中產生ArrayList對象,但是不能明確匯入  java.util.*;
      public class test
      {
       public static void main(String args[])
       {
        java.util.ArrayList al = new java.util.ArrayList();
       }
      }
     6、撰寫一個具有public 、private、protected、friendly的資料成員和函數,並且產生一個對象進行觀察,當你取用類中成員的時候,有什麼編譯訊息?
      package test;
      public class test
      {
       public int a;
       private int b;
       protected int c;
       int d;
       
       public void methodA(){}
       private void methodB(){}
       protected void methodC(){}
       void methodD(){}
       
       public static void main(String args[])
       {
        test T = new test();
        T.a=1;
        T.b=1; //在不同/同一個包中cannot access the private members
        T.c=1; //在不同的包中cannot access the protected members
        T.d=1; //在不同的包中cannot access the friendly members
        
        T.methodA();
        T.methodB(); //在不同/同一個包中cannot access the private members
        T.methodC(); //在不同的包中cannot access the protected members
        T.methodD(); //在不同的包中cannot access the friendly members
       }
      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             7、撰寫一個class,讓他其中的成員具有protected,在同一個檔案內撰寫第二個class,並且在這裡操作第一個class中的protected資料
      class protectedDemo
      {
       protected int i;
      }
      public class test
      {
       public static void main(String args[])
       {
        protectedDemo pd = new protectedDemo();
        pd.i=10;
        System.out.println(pd.i);
       }
      }
      這個程式其實考察的是我們的"在同一個包中protected相當於包存取控制(friendly)"
    12、Create the following file in the c05/local directory (presumably in your CLASSPATH):
      //: c05:local:PackagedClass.java
      //=M @echo compile by hand to see results
      package c05.local;
      class PackagedClass {
        public PackagedClass() {
          System.out.println(
            "Creating a packaged class");
        }
      } ///:~
      
      Then create the following file in a directory other than c05:
      
      
      //: c05:foreign:Foreign.java
      //=M @echo compile by hand to see results
      package c05.foreign;
      import c05.local.*;
      public class Foreign {
         public static void main (String[] args) {
            PackagedClass pc = new PackagedClass();
         }
      } ///:~
      
      Explain why the compiler generates an error. Would making the Foreign class part of the c05.local package change anything?
      因為PackagedClass並非public的,而是friendly的,是包存取控制,只能在該包內的成員才能使用,如果把他放到和Foreign一樣的目錄,那麼他們等於說是在同一個包中,當然可以順利訪問。
      
這一章主要就是將了一下存取控制符,基本上不是很難,下一章我們講解重複運用class

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.