Java基礎知識篇02——封裝

来源:https://www.cnblogs.com/baiye123/p/18131950
-Advertisement-
Play Games

大家好,我是白夜,今天給大家聊聊面向對象的三大特征——封裝 一、包(package) 1.1、包的引入 先來看看我們之前寫的代碼結構 以上代碼存在的問題 所有類寫在一個目錄下麵,非常難管理,因為以後項目不可能只有這麼幾個類,當類數量很大的時候,就不容易管理了。 不能寫同名但是不同需求的類。 為瞭解決 ...


大家好,我是白夜,今天給大家聊聊面向對象的三大特征——封裝

一、包(package)

1.1、包的引入

先來看看我們之前寫的代碼結構

圖片01

以上代碼存在的問題

  1. 所有類寫在一個目錄下麵,非常難管理,因為以後項目不可能只有這麼幾個類,當類數量很大的時候,就不容易管理了。
  2. 不能寫同名但是不同需求的類。

為瞭解決這些問題,我們需要把不同的東西放到專門的裡面,進行分類管理。也就是通過文件夾進行管理,Java 中的文件夾就是

1.2、定義包

包命名規範:一般是公司功能變數名稱反寫.項目名.模塊名字.子模塊名;

要求:包名是全英文小寫。

例如 : itsource.cn 功能變數名稱

package cn.itsource.erp.oa.domain; 自動化辦公

package cn.itsource.erp.sa.entity; 系統管理

package cn.itsource.packagedemo;// 聲明包

/**
 * 包package
 */
public class PackageDemo {

	public static void main(String[] args) {
		new java.util.Date();
		new java.sql.Date(1L);
		System.out.println();
	}
}

1.3、導入包

當我們需要使用別人或者 JDK 中的類的時候,就需要告知 JVM 從什麼地方去載入這個類,這個過程就是導包

其實本質是導入包中的類。

導入包的語法 :

import 包名.子包名.類名

註意:

  1. 導入包的代碼應該在聲明包(就是該類所在的包)的後面,聲明類的前面。

  2. import java.util; 表示導入本包中所有會使用到的 util 包中的類,只會導入 util 包下麵直接的類型,不包括util 包的子包中的類型。

  3. java.lang是核心包,下麵的直接類型是自動導入的;

    例如:String、System類,lang 包的子包中的類型不會自動導入,需要手動導入。

  4. 在一個類中會用到同名不同包的時候必須使用全限定路徑

    例如:同時使用 java.util.Date 和 java.sql.Date

package cn.itsource.packagedemo;//聲明包
import java.util.*;// 只會導入util包下使用到的類

/**
 * 包package
 */
public class PackageDemo {

	public static void main(String[] args) {// String是java.lang核心包下的,程式會自動導入;
		// 使用Arrays類中的toString方法
//		String str = java.util.Arrays.toString(new int[]{1, 2, 3});// 每次都寫全限定類名比較麻煩
		
		// 使用Arrays類中的sort方法排序
//		java.util.Arrays.sort(new int[]{3, 2, 1});
		
		// 用自動導包可以簡化上面代碼
		String str = Arrays.toString(new int[]{1, 2, 3});// 每次都寫全限定類名比較麻煩
		System.out.println(str);
		Arrays.sort(new int[]{3, 2, 1});
		
		// 當使用同名不同包的多個類怎麼用? 必須用全限定類名
		new java.util.Date();// java.util包下
		new java.sql.Date(1L);// java.sql包下
	}
}

1.4、Java中常用的包(瞭解)

java/ javax(java 增強包)

java.lang (java 的核心包--基本包) 幫我們自動導包的

java.util(java 的工具包 --集合框架 ArrayList LinkedList)

java.io(java IO包input-output 讀寫文件)

java.net (網路編程)

java.awt/javax.swing(java的圖形化界面)

java.math 數學相關的包

java.sql 資料庫相關的包

java.text 是文本格式化相關的包

java.time 時間相關的包

二、封裝

2.1、為什麼要封裝

來看下麵一個案例

package cn.itsource.potting1;

/**
 *	賬戶Account類
 *	封裝引入
 */
public class Account {
	/** String類型成員變數姓名name */
	protected String name;
	
	/** String類型成員變數密碼pwd */
	String pwd;
	
	/** double類型成員變數餘額money */
	double money;
	
	/** boolean類型成員變數是否是vip用戶 */
	boolean vip;
	
	/**
	 * Account類無參構造
	 */
	public Account() {}
	
	/**
	 * 有4個參數構造方法
	 * @param n
	 * @param p
	 * @param m
	 * @param v
	 */
	public Account(String n, String p, double m, boolean v) {
		name = n;// 將局部變數n賦值給成員變數name
		pwd = p;// 將局部變數p賦值給成員變數pwd
		money = m;// 將局部變數m賦值給成員變數money
		vip = v;// 將局部變數v賦值給成員變數vip
	}
	
	/**
	 * 獲取當前成員變數money的值
	 * @return
	 */
	public double getMoney() {
		return money;
	}
}

測試類:
package cn.itsource.potting1;

/**
 *	Account測試類
 *	封裝的引入
 */
public class AccountTest {

	public static void main(String[] args) {
		// 創建Account對象,調用無參構造
		Account acc1 = new Account();
		// 給acc1成員變數賦值
		acc1.name = "某菲";
		acc1.pwd = "6969";
		acc1.money = 1.0;
		acc1.vip = false;
		// 列印acc1成員變數的值
		System.out.println(acc1.name);
		System.out.println(acc1.pwd);
		System.out.println(acc1.money);
		System.out.println(acc1.vip);
		// acc1調用getMoney方法
		double money = acc1.getMoney();// 因為getMoney方法是非static修飾,並且有返回值,所以用acc1調用,用double變數接收
		System.out.println(money);
		
		// 需求:當money達到50000.00的時候,會將vip升級為true。現在,能不能沒有達到5萬就不能升級。
		acc1.vip = true;// 這裡沒有經過任何許可權判斷,直接修改了值,不安全。所以,用封裝解決這個問題。
		System.out.println(acc1.vip);// true		
	}
}

而在 Java 中是通過封裝來完成保護內部成員的目的

2.2、封裝的作用

封裝是為了保護內部數據的安全:

  1. 不希望在外部類中隨意訪問類中的成員變數
  2. 達到許可權要求的才能訪問。
  3. 只是獲取數據的時候。例如:單例模式。
  4. 我們在程式設計的時候就追求“高內聚、低耦合”:
  • 高內聚:類的內部數據操作細節自己完成,不允許外部干涉;
  • 低耦合:僅對外部暴露少量的方法用於使用。

2.3、封裝的使用

  1. 如何控製程序中的訪問 ?

    通過給類中的成員(欄位,方法,構造方法)添加訪問許可權修飾符來實現封裝(訪問控制)。

  2. 什麼是訪問許可權:簡單的認為訪問許可權就是不同級別的人能夠乾不同級別的事,不同級別的人能看到的頁面是不同的。

    例子:比如做一個系統,不同人登錄進去的訪問許可權不一樣;

  3. 訪問許可權修飾符:

    public 最大許可權,被其修飾的成員,在任意目錄下,都可以訪問到 (所有類)

    protected 在同包類和子類中都可以訪問

    預設不寫 只能在同包類中訪問

    private 只能在當前類中訪問

    圖片02

  4. 封裝的步驟:

    1. 將類的屬性設置為 private,這樣外部就不能直接訪問。
    2. 提供公共的 getter 方法用於獲取屬性值,通常是 public 的。
    3. 提供公共的 setter 方法用於設置屬性值,也是 public 的,並可以在其中添加邏輯檢查。
    4. 提供一個無參構造,有參構造根據需求確定是否要寫。
    5. 該類用 public 修飾。

    圖片03

    public class Account {// 5. 該類用 public 修飾
    	//1. 私有化成員變數(用 private 修飾成員變數)
    	private String name;
    	
    	private String pwd;
    	
    	// 4. 提供一個無參構造
    	public Account() {}
    	
    	// 有參構造根據實際需求,決定是否要寫
    	public Account(String n, String p) {
    		name = n;// 將局部變數賦值給成員變數
    		pwd = p;	
    	}
    	
    	/**
    	 *  2. 為每一個成員變數提供合理的 public void setName(String n) 方法
    	 * 	給成員變數name賦值方法
    	 * @param n
    	 */
    	public void setName(String n) {
    		// 可以寫判斷條件
    		name = n;// 將局部變數n賦值給成員變數 name
    	}
    		
    	public void setPwd(String p) { pwd = p; }
    	
    	/**
    	 * 2. 為每一個成員變數提供合理的	public String getName() 方法
    	 * 獲取成員變數 name 的值
    	 * @return
    	 */
    	public String getName() {
    		// 可以寫判斷條件
    		return name;// 直接返回成員變數 name
    	}
    	
    	public String getPwd() { return pwd; }	
    }
    
    /**
     *	Account 測試類
     *	封裝的引入
     */
    public class AccountTest {
    	public static void main(String[] args) {
    		// 創建Account對象,調用無參構造
    		// Account acc1 = new Account();
    		// 給 acc1 成員變數賦值
    		/*
    		 * 因為 private 修飾成員變數後,不能在其他類中使用了。
    		acc1.name = "小七";
    		acc1.pwd = "6969";
    		*/
    		// 使用有參構造賦值
    		Account acc1 = new Account("小七", "6969");
    		
    		// 列印acc1成員變數的值
    //		System.out.println(acc1.name);// 因為 private 修飾成員變數後,不能在其他類中使用了。
    //		System.out.println(acc1.pwd);
    		
    		// 因為封裝了,所以只能調用:public 返回值 getXxx() 獲取成員變數的值
    		String name = acc1.getName();// acc1 調用 getName 方法獲取成員變數 name 的值
    		String pwd = acc1.getPwd();// acc1 調用 getPwd 方法獲取成員變數 pwd 的值
    		// 列印上面獲取的值
    		System.out.println(name);
    		System.out.println(pwd);
    		
    		// 當需要修改創建好的對象的成員變數值,用 set 方法賦值
    		acc1.name("小八");	
    		String name2 = acc1.getName();
    		System.out.println(money2);		
    	}
    }
    

    2.4、 封裝的註意事項

    1. 不是只有 private 才叫封裝,private 只是最大限度的封裝而已。
    2. get 和 set 方法都是只能獲取或者賦值一個成員變數,**不能 **set(String n, double m, boolean v) 賦值3個成員變數。
    3. 單一職能原則:功能最小化,不要想著一個方法寫完所有的功能,因為代碼復用率高。

    2.5、封裝的好處

    • 增強安全性:隱藏數據和方法的實現細節,防止外部直接訪問,降低因錯誤使用而導致的風險。
    • 提高復用性:封裝後的代碼更容易被其他程式或模塊復用,因為它們的實現細節對於使用者來說是透明的。
    • 便於維護:封裝使得代碼修改時影響範圍局限,提高了代碼的可維護性。

三、this關鍵字

this 的概念:

​ this 指代當前對象,即,哪個對象調用就指代哪個對象

3.1、this 的使用

1.   解決局部變數和成員變數的二義性【set 方法和有參構造中形參跟成員變數同名不同義】

public Account(String name,String pwd) {
	// 要解決二義性問題,就需要用到this,加上this,就會直接從成員變數位置找name
	this.name = name;
	this.pwd = pwd;
}

1.   本類中構造方法之間的相互調用,但是必須是構造方法內的第一句。

package cn.itsource.task.topic02;

public class People {
    private String name;
    private boolean sex;
    private int age;
    private int weight;
    public People(){

    }
    public People(String name, boolean sex, int age, int weight){
        this(name, sex, age);
        this.weight = weight;
    }
    public People(String name, boolean sex, int age){
        this(name, sex);
        this.age = age;
    }
    public People(String name, boolean sex){
        this(name);
        this.sex = sex;
    }
    public People(String name){
        this.name = name;
    }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public boolean isSex() { return sex; }

    public void setSex(boolean sex) { this.sex = sex; }

    public int getAge() { return age; }

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

    public int getWeight() { return weight; }

    public void setWeight(int weight) { this.weight = weight; }
}

四、構造方法和set方法的區別

  • 構造方法可以為多個成員變數賦值,set只能對一個進行賦值;
  • 構造方法由JVM自動調用,set需要手動調用;
  • 構造方法針對同一個對象只能調用一次,set方法針對同一個對象可以調用多次;
  • 構造方法用於給變數賦值,set可以給變數賦值或者修改值;
  • 構造可以使代碼更加簡潔,set方法靈活性更高。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JS解混淆 最近在整理之前和一些同伴的分享資料,發現時間已經過了好久,特此整理一些有價值的分享記錄。 JS混淆 學習js混淆可以逆向分析混淆和加密過程,實戰可用於爬蟲和滲透信息獲取 本文檔用於初步介紹js混淆的基礎概念以及如何解混淆、調試,便於幹掉反爬蟲和滲透信息收集思路拓展 概念解釋 混淆/加密 ...
  • 前言 我們已經介紹了radash的相關信息和部分Array相關方法,詳情可前往主頁查看; 本篇我們繼續介紹radash中Array的相關方法; 下期我們將介紹解析radash中剩餘的 Array相關方法,並整理出Array方法使用目錄,包括文章說明和腦圖說明。 Radash的Array相關方法詳解 ...
  • 大家好,我是 Java陳序員。 今天,給大家介紹一個基於 Vue 全家桶實現的“網易雲”播放器。 關註微信公眾號:【Java陳序員】,獲取開源項目分享、AI副業分享、超200本經典電腦電子書籍等。 項目介紹 YesPlayMusic —— 一款高顏值的第三方網易雲播放器,支持 Windows / ...
  • 本文分享自華為雲社區《3月閱讀周·你不知道的JavaScript | ES6生成器,看似同步的非同步流程式控制製表達風格》,作者: 葉一一。 生成器 打破完整運行 JavaScript開發者在代碼中幾乎普遍依賴的一個假定:一個函數一旦開始執行,就會運行到結束,期間不會有其他代碼能夠打斷它並插入其間。 ES ...
  • 目錄一、爬取目標1.1 效果截圖1.2 演示視頻1.3 軟體說明二、代碼講解2.1 爬蟲採集模塊2.2 軟體界面模塊2.3 日誌模塊三、獲取源碼及軟體 一、爬取目標 用python開發的xhs爬蟲採集軟體,可自動抓取小紅書評論數據,並且含二級評論數據。 為什麼有了源碼還開發界面軟體呢?方便不懂編程代 ...
  • 1、 Pythonic - 很Python 寫一段代碼生成1到100之間的數字的平方的列表,答案是: 1, 4, 9, 16... 如果你這樣寫,你就不Pythonic了: 解釋 nums = [] for i in range(1, 101): nums.append(i*i) print(num ...
  • 拓展閱讀 MySQL View MySQL truncate table 與 delete 清空表的區別和坑 MySQL Ruler mysql 日常開發規範 MySQL datetime timestamp 以及如何自動更新,如何實現範圍查詢 MySQL 06 mysql 如何實現類似 oracl ...
  • C++ 解引用 獲取記憶體地址和值 在上一頁的示例中,我們使用了指針變數來獲取變數的記憶體地址(與引用運算符 & 一起使用)。但是,你也可以使用指針來獲取變數的值,這可以通過使用 * 運算符(解引用運算符)來實現: string food = "Pizza"; // 變數聲明 string* ptr = ...
一周排行
    -Advertisement-
    Play Games
  • 一個自定義WPF窗體的解決方案,借鑒了呂毅老師的WPF製作高性能的透明背景的異形視窗一文,併在此基礎上增加了滑鼠穿透的功能。可以使得透明窗體的滑鼠事件穿透到下層,在下層窗體中響應。 ...
  • 在C#中使用RabbitMQ做個簡單的發送郵件小項目 前言 好久沒有做項目了,這次做一個發送郵件的小項目。發郵件是一個比較耗時的操作,之前在我的個人博客裡面回覆評論和友鏈申請是會通過發送郵件來通知對方的,不過當時只是簡單的進行了非同步操作。 那麼這次來使用RabbitMQ去統一發送郵件,我的想法是通過 ...
  • 當你使用Edge等瀏覽器或系統軟體播放媒體時,Windows控制中心就會出現相應的媒體信息以及控制播放的功能,如圖。 SMTC (SystemMediaTransportControls) 是一個Windows App SDK (舊為UWP) 中提供的一個API,用於與系統媒體交互。接入SMTC的好 ...
  • 最近在微軟商店,官方上架了新款Win11風格的WPF版UI框架【WPF Gallery Preview 1.0.0.0】,這款應用引入了前沿的Fluent Design UI設計,為用戶帶來全新的視覺體驗。 ...
  • 1.簡單使用實例 1.1 添加log4net.dll的引用。 在NuGet程式包中搜索log4net並添加,此次我所用版本為2.0.17。如下圖: 1.2 添加配置文件 右鍵項目,添加新建項,搜索選擇應用程式配置文件,命名為log4net.config,步驟如下圖: 1.2.1 log4net.co ...
  • 之前也分享過 Swashbuckle.AspNetCore 的使用,不過版本比較老了,本次演示用的示例版本為 .net core 8.0,從安裝使用開始,到根據命名空間分組顯示,十分的有用 ...
  • 在 Visual Studio 中,至少可以創建三種不同類型的類庫: 類庫(.NET Framework) 類庫(.NET 標準) 類庫 (.NET Core) 雖然第一種是我們多年來一直在使用的,但一直感到困惑的一個主要問題是何時使用 .NET Standard 和 .NET Core 類庫類型。 ...
  • WPF的按鈕提供了Template模板,可以通過修改Template模板中的內容對按鈕的樣式進行自定義。結合資源字典,可以將自定義資源在xaml視窗、自定義控制項或者整個App當中調用 ...
  • 實現了一個支持長短按得按鈕組件,單擊可以觸發Click事件,長按可以觸發LongPressed事件,長按鬆開時觸發LongClick事件。還可以和自定義外觀相結合,實現自定義的按鈕外形。 ...
  • 一、WTM是什麼 WalkingTec.Mvvm框架(簡稱WTM)最早開發與2013年,基於Asp.net MVC3 和 最早的Entity Framework, 當初主要是為瞭解決公司內部開發效率低,代碼風格不統一的問題。2017年9月,將代碼移植到了.Net Core上,併進行了深度優化和重構, ...