Java類——封裝

一、爲什麼要封裝?

\quad封裝是面向對象的三大特徵之一(另外兩個是繼承和多態),它指的是將對象的狀態信息隱藏在對象內部,不允許外部程序直接訪問對象內部的信息,而是通過該類提供的方法來實現對內部信息的操作和訪問。
\quad比如Person類的屬性中可能包含age,age屬性只能隨着時間流逝才能變大,通常不能隨意修改Person對象的age屬性。對一個類或對象實現封裝,好處很多:

  • 隱藏類的實現細節
  • 讓使用者只能通過事先預定的方法來訪問數據,從而可以在該方法里加入控制邏輯,限制對屬性的不合理訪問
  • 便於修改,提高代碼的可維護性

\quad爲了實現良好的封裝,通常從以下兩個方面着手:

  • 將對象的屬性和實現細節隱藏起來,不允許外部直接訪問
  • 把方法暴露出來,讓方法來操作或訪問這些屬性

二、訪問控制符

\quadJava提供3個訪問控制符:private, protected, public,分別代表了3個訪問控制級別。另外還有一個不加任何訪問控制符的訪問控制級別,提供了4個訪問控制級別。訪問控制級別從小到大如下圖所示:
在這裏插入圖片描述
\quad 4個訪問控制級別中的defalut並沒有對應的訪問控制符,當不使用任何訪問控制符來修飾類或者類成員時,系統默認使用該訪問控制級別。4個訪問控制級別詳解如下:

  • private:若類中某個成員使用private修飾時,該成員只能在該類的內部被訪問。顯然,private用於修飾屬性最合適,使用它來修飾屬性就可以把屬性隱藏在類的內部。
  • defalut:若類中某個成員不被任何訪問控制符修飾,則稱其爲默認訪問控制。defalut訪問控制的成員或頂級類可以被相同包下的其他類訪問。
  • protected:若類中某個成員使用protected修飾,那麼該成員既可以被同一個包的其他類訪問,也可以被不同包的子類訪問。通常情況下,若使用protected來修飾一個方法,則是希望其子類來重寫這個方法。
  • public:若類中某個成員使用public修飾,那麼該成員或頂級類可以被所有類訪問,不管訪問類和被訪問類是否在同一包中,是否具有父子繼承關係。
private default protected public
同一個類中 \surd \surd \surd \surd
同一個包中 \surd \surd \surd
子類中 \surd \surd
全局範圍內 \surd

\quad對於頂級類而言,只能有兩種訪問控制級別:public和默認。頂級類不能使用private, protected修飾,因爲頂級類既不處於任何類的內部,也就沒有其外部類的子類了,因此private, protected訪問對於頂級類沒有意義。使用public修飾的頂級類可被所有類訪問;不使用的話只能被同一包中的所有類訪問。
\quad拿Person類舉個例子。Person類如下:

public class Person {
    private int age;
    private String name;
    public void setName(String name)
    {
        if(name.length() > 10 || name.length() < 2)
        {
            System.out.println("您設置的名字不符合要求");
            return;
        }
        this.name = name;
    }
    public String getName() { return this.name; }
    public void setAge(int age)
    {
        if(age >= 150 ||  age < 0)
        {
            System.out.println("您設置的年齡不合法");
            return;
        }
        this.age = age;
    }
    public int getAge() { return this.age; }
}

\quad測試Person類如下:

public class TestPerson {
    public static void main(String[] args)
    {
        Person p = new Person();
        p.setName("程勇");
        p.setAge(23);
        System.out.println(p.getName());
        System.out.println(p.getAge());
    }
}

\quad輸出結果如下:

程勇
23

\quad如上述程序所示,TestPerson類中main方法不可直接修改Person對象的name和age屬性,只能通過各自的set方法來操作這兩個屬性值。這樣就能在set方法中增加自己的控制邏輯,從而保證Person對象的 name 和age屬性合法。
\quad總結下訪問控制符使用的幾條基本原則

  • 類中絕大部分屬性都應該使用private修飾,除了一些static修飾的全局變量屬性。除此之外,有些方法只是用於輔助實現該類的其他方法,這些方法稱爲工具方法,也應使用private修飾。
  • 若某個類主要用於其他類的父類,這個類包含的大部分方法可能僅希望被其子類重寫,而不想被外界直接調用,應使用protected修飾。
  • 類的構造器使用public修飾,暴露給其他類中創建該類的對象。頂級類通常的都希望被其他類自由調用,所以大部分頂級類都是public修飾。

三、package和import

1、package

\quad有成千上萬的類,類名難免會有重複,如何解決類的命名衝突問題呢?Java引入了package機制,即在類名前加一個前綴來限定這個類。
\quadJava允許將一組功能相關的類放在同一個package下,從而組成邏輯上的類庫單元。若希望將一個類放在指定的包結構下,在該類所在源文件第一行加入一句

package packageName;

\quad一旦在Java源文件中使用了package語句,則意味着該源文件裏定義的所有類都屬於這個包。位於包中的每個類的完整類名都應該是包名和類名的組合,如果其他人需要使用該包下的類,也應該使用包名+類名的組合。

package lee;
public class Hello {
    public static void main(String[] args)
    {
        System.out.println("Hello World!");
    }
}

\quadjavac -d . Hello.java編譯上述代碼,則會在該路徑上生成一個lee文件,並將Hello.java放入這個文件中去。此時再執行java Hello.java則能得到正確結果。
在這裏插入圖片描述
\quad此時如果進入文件夾lee,再使用java Hello.java會報錯,表明此時Hello類已經與lee包綁定在一起,只能通過包名.類名,即lee.Hello訪問。上述命令操作如下圖所示:
在這裏插入圖片描述
\quad值得注意的是:不要認爲只要把生成的class文件放在某個目錄下,這個目錄名就成了這個類的包名。包名必須在Java源文件中通過package語句指定,而不是靠目錄名來指定。Java的包機制需要2個方面保證:

  • 源文件裏使用package語句指定包名
  • class文件必須放在對應的路徑下

\quadpackage語句一個源文件中只能有一條,即一個源文件只能指定一個包。該源文件中可以定義多個類,則這些類將全部位於該包下。
\quad如果沒有顯示指定package語句則處於默認包下。實際開發中不會這樣做。

2、import

\quad正如下面看到的,如果需要使用不同包中的其他類時,總是需要使用該類的全名,這是一件很繁瑣的事情。爲簡化編程,Java引入了import關鍵字,import可以向某個Java文件中導入指定包層下某個類或全部類。import語句應出現在package語句(如果有的話)之後,可以有多條import語句用於導入多個包層次下的類。舉個例子:

import java.util.HashMap;  // 導入某個類
import java.util.*;  // 導入java.util包層次下所有類

\quad一旦在Java源文件中使用import語句來導入指定類,在該源文件中使用這些類時可以省略包前綴。Java默認所有的源文件都導入java.lang包下的所有類,包括System, String, Math, Integer, Float, Double, Byte等。

3、Java中常用的包

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章