首頁 > 軟體

Java封裝的實現存取限定符、包

2022-08-23 14:00:02

一. 封裝

封裝是物件導向的三大特性之一;物件導向程式三大特性:封裝、繼承、多型 。

封裝:將資料和運算元據的方法進行有機結合,隱藏物件的屬性和實現細節,僅對外公開介面來和物件進行互動(簡單來說就是套殼遮蔽細節)。

用生活中的實物來理解封裝,比如電腦:

對於電腦這樣一個複雜的裝置,提供給使用者的就只是:開關機、通過鍵盤輸入,顯示器,USB插孔等,讓使用者來和計算機進行互動,完成日常事務。

但實際上:電腦真正工作的卻是CPU、顯示卡、記憶體等一些硬體元件。對於計算機使用者而言,不用關心內部核心部件,比如主機板上線路是如何佈局的,CPU內部是如何設計的等,使用者只需要知道,怎麼開機、怎麼通過鍵盤和滑鼠與計算機進行互動即可。因此計算機廠商在出廠時,在外部套上殼子,將內部實現細節隱藏起來,僅僅對外提供開關機、滑鼠以及鍵盤插孔等,讓使用者可以與計算機進行互動即可

二. 存取限定符(修飾符)

Java中主要通過類和存取許可權來實現封裝:類可以將資料以及封裝資料的方法結合在一起,更符合人類對事物的認知,而存取許可權用來控制類或者類中方法或者欄位能否直接在類外使用。Java中提供了四種存取限定符:

public:公開的,可以理解為一個人的外貌特徵,誰都可以看得到

protected:受保護的,涉及到繼承中的知識,繼承部落格中詳細介紹

default: 什麼都不寫時的預設許可權,對於自己家族中(同一個包中)不是什麼祕密,對於其他人來說就是隱私了

private:私有的,只有自己知道,其他人都不知道

通過下面給出的程式碼範例理解封裝:

class Person {
    private String name;
    //private修飾的成員變數只能在本類中存取
    private int age;

    String sex;
    //這裡不加修飾符即為預設許可權,預設是default許可權

    public String getName() {
        return name;
    }
    //在其他類中不能直接存取name和age,
    //但可以在本類中提供公開的(public修飾)存取方法和外界進行互動
    //這裡就是對成員變數進行了封裝
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void show() {
        System.out.println("姓名:"+name+" 年齡: "+age);
    }
}

public class Test {

    public static void main(String[] args) {
        Person person = new Person();
        //person.name = "bit";//不能直接進行存取
        person.setName("XIN-XIANG榮");
        person.setAge(21);
        //通過提供Person類中提供的方法間接進行存取
        System.out.println(person.getName()+" => "+person.getAge());
    }
}

一般情況下成員變數設定為private,成員方法設定為public,通過這個例子就可以很好的理解封裝了,這裡對 類 內部的實現細節進行了隱藏/封裝,對 外 只提供一些公開的方法供其他使用者進行存取。

【存取限定符的使用場景】:

  • 我們希望類要儘量做到 “封裝”, 即隱藏內部實現細節, 只暴露出 必要 的資訊給類的呼叫者.
  • 因此我們在使用的時候應該儘可能的使用 比較嚴格 的存取許可權;例如如果一個方法能用 private, 就儘量不要用 public.
  • 另外, 還有一種 簡單粗暴 的做法: 將所有的欄位設為 private, 將所有的方法設為 public. 不過這種方式屬於是對存取許可權的濫用, 不過最好寫程式碼的時候思考該類提供的欄位方法到底給 “誰” 使用(是類內部自己用, 還是類的呼叫者使用, 還是子類使用)

三. 包

1. 包的概念

在物件導向體系中,提出了一個軟體包的概念,即:為了更好的管理類,把多個類收集在一起成為一組,稱為軟體包。 有點類似於目錄。比如:為了更好的管理電腦中的圖片,一種好的方式就是將相同屬性的圖片放在相同檔案下,也可以對某個資料夾下的圖片進行更詳細的分類 。

在Java中也引入了包,包是對類、介面等的封裝機制的體現,是一種對類或者介面等的很好的組織方式,比如:一個包中的類不想被其他包中的類使用。包還有一個重要的作用:在同一個工程中允許存在相同名稱的類,只要處在不同的包中即可

2. 匯入包中的類

2.1 匯入方法一

Java 中已經提供了很多現成的類供我們使用. 例如Date類:可以使用 java.util.Date 匯入 java.util 這個包中的 Date類.

public class Test1 {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
        // 得到一個毫秒級別的時間戳
        System.out.println(date.getTime());
    }
}

2.2 匯入方法二

但是這種寫法比較麻煩一些, 可以使用 import語句匯入包

import java.util.Date;
public class Test1 {
    public static void main(String[] args) {
        Date date = new Date();
        // 得到一個毫秒級別的時間戳
        System.out.println(date.getTime());
    }
}

2.3 匯入方法三

如果需要使用 java.util 中的其他類, 可以使用 import java.util.* ,這裡可以匯入java.util這個包中的所有類,但要注意不是一下子將所有類都導進來,在程式碼中用到誰就會匯入誰。

import java.util.*;
public class Test1 {
    public static void main(String[] args) {
        Date date = new Date();
        // 得到一個毫秒級別的時間戳
        System.out.println(date.getTime());
    }
}

但是更建議顯式的指定要匯入的類名. 否則還是容易出現衝突的情況.

import java.util.*;
import java.sql.*;
public class Test1 {
    public static void main(String[] args) {
// util 和 sql 中都存在一個 Date 這樣的類, 此時就會出現歧義, 編譯出錯
        Date date = new Date();
        System.out.println(date.getTime());
    }
}

// 編譯出錯
//Error:(5, 9) java: 對Date的參照不明確
//java.sql 中的類 java.sql.Date 和 java.util 中的類 java.util.Date 都匹配

在這種情況下需要使用完整的類名

import java.util.*;
import java.sql.*;
public class Test1 {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
        System.out.println(date.getTime());
    }
}

2.4 匯入靜態的方法和欄位

import static java.lang.Math.*;
public class Test {
    public static void main(String[] args) {
        double x = 30;
        double y = 40;
// 靜態匯入的方式寫起來更方便一些.
// double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        double result = sqrt(pow(x, 2) + pow(y, 2));
        System.out.println(result);
    }
}

//對比正常的匯入和使用
import java.lang.Math;
public class Test1 {
    public static void main(String[] args) {
        double x = 30;
        double y = 40;
        double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        System.out.println(result);
    }
}

3. 自定義包

3.1 基本使用規則:

  • 在檔案的最上方加上一個 package 語句指定該程式碼在哪個包中.
  • 包名需要儘量指定成唯一的名字, 通常會用公司域名的顛倒形式(例如com.bat.demo1 ).
  • 包名要和程式碼路徑相匹配. 例如建立 com.bat.demo1 的包, 那麼會存在一個對應的路徑 com/bat/demo1 來儲存程式碼
  • 如果一個類沒有 package 語句, 則該類被放到一個預設包中

3.2 IDEA中創鍵自定義包

在 IDEA 中先新建一個包: 右鍵 src -> 新建 -> 包

在彈出的對話方塊中輸入包名, 例如 com.bat.demo1 ,敲入回車即可

在包中建立類, 右鍵包名 -> 新建 -> 類, 然後輸入類名回車即可.

此時可以看到我們的磁碟上的目錄結構已經被 IDEA 自動建立出來了

同時我們也看到了, 在新建立的 Test.java 檔案的最上方, 就出現了一個 package 語句

4. 不同包中的存取許可權控制

Computer類位於com.bat.demo1包中,TestComputer位置com.bat.demo2包中

package com.bat.demo1;

public class Computer {
    private String cpu; // cpu
    private String memory; // 記憶體
    public String screen; // 螢幕
    String brand; // 品牌

    public Computer(String brand, String cpu, String memory, String screen) {
        this.brand = brand;
        this.cpu = cpu;
        this.memory = memory;
        this.screen = screen;
    }

    public void Boot() {
        System.out.println("開機~~~");
    }

    public void PowerOff() {
        System.out.println("關機~~~");
    }

    public void SurfInternet() {
        System.out.println("上網~~~");
    }
}

注意:如果去掉Computer類之前的public修飾符,Computer類為預設許可權,只能在同一包中存取,程式碼也會編譯失敗

5. 常見的包

  • java.lang:系統常用基礎類(String、Object),此包從JDK1.1後自動匯入。
  • java.lang.reflect:java 反射程式設計包;
  • java.net:進行網路程式設計開發包。
  • java.sql:進行資料庫開發的支援包。
  • java.util:是java提供的工具程式包;(集合類等) 非常重要
  • java.io:I/O程式設計開發包。

總結

到此這篇關於Java封裝實現存取限定符、包的文章就介紹到這了,更多相關Java存取限定符 包內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com