Java:封装的概念,UML类图,构造方法,this关键字,static关键字,方法重载,包package
????????
????????oop三大特性:封裝,繼承,多態
oop一般指面向對象程序設計(一種計算機編程架構)
一、封裝的概念:
? ? ? ?將東西包在一起,然后以新的完整形式呈現出來
? ? ? ? ? ? ? ? 將方法和字段一起包裝到一個單元中,單元以類的形式實現
? ? ? ? 信息隱藏,隱藏對象的實現細節,不讓外部直接訪問到
????????
? ? ? ? ? ? ? ? 將數據和方法包裝進類中,加上具體實現的隱藏(訪問修飾符),共同被稱作封裝,其結果是一個同時帶有特征和行為的數據類型
? ? ? ? ? ? ? "? 定義類,定義其屬性,方法的過程稱為封裝類"
=========================================================================
? ? ?將東西包在一起,然后以新的完整形式呈現出來
? ? ? ? ? ? ? ? 將方法和字段一起包裝到一個單元中,單元以類的形式實現:
這個類比我們以前寫的c的結構體
定義了一個結構體,結構體里面
int age ,char *name ,double score;這些屬于student的屬性
這有兩個函數introduce 和testFunc? 這些相當于方法
類可以理解成student
java也是類似的
? ? ? 信息隱藏,隱藏對象的實現細節,不讓外部直接訪問到:
除了類比結構體以外,比c語言多了一些概念,信息隱藏
函數的實現,函數體不讓人家看到,只提供了函數api的接口
? ? ? ? ? 將數據和方法包裝進類中,加上具體實現的隱藏(訪問修飾符),共同被稱作封裝,其結果是一個同時帶有特征和行為的數據類型:
這個隱藏和前面的信息隱藏不一樣,
這面的隱藏也就是訪問修飾符
也就是在結構體的概念上加了一些訪問修飾符,共同被稱為封裝
特征就是int age ;??
????????????????char *name ;
????????????????double score;
行為就是那兩個函數啦
????????????????void (*introduce)(int age,int name,int score);
?? ?????????????????void (*testFunc)();
"? 定義類,定義其屬性,方法的過程稱為封裝類":
我們現在封裝一個結構體:它和那個c語言的結構體是非常像的,我們直接拿過來
(補充:下面的類叫Demo1)
在封裝類的時候,他的語法沒有struct 用class
在java中沒有char *這樣的指針,對于字符串有一個String這樣的類型
double 是可以的
java也沒有函數指針的概念,我們直接把函數名寫上,
可以把int age,int name,int score去掉,不用傳參
因為面向對象的特性是什么?
????????????????????????這個方法introduce能訪問屬于自己的特征屬性int age;? ? ? ?也就不需要額外的傳參
?????????????????????????????????????????????????????????????????????????????????????????? ?char *name;
?????????????????????????????????????????????????????????????????????????????????????????? ?double score;
?我們c語言為什么要傳參,因為c語言沒有面向對象的概念,他是面向過程的編程語言,在函數調用的時候設置一些形參,調函數的時候傳遞這些形參int age;?
?????????????????????????????????????????????????????????????????????????????????char *name;
???????????????????????????????????????????????????????????????????????????????????double score;
Java其實也有這些所謂的形參,只不過在下面這種情況底下,自己的成員變量進行訪問的時候,就不需要額外的傳參了,直接訪問
剛才我們編寫代碼的過程就是封裝了一個類
這個類里面有三個屬性分別是age,name,score分別是int 型,字符型,double型
我們還分裝了兩個方法 ,? 方法=函數
封裝類以后我們如何使用這個類呢?
如果用指針定義這個結構體的話
先給他分配空間,然后才可以對里面的東西進行操作
Java也一樣,也需要給他分配個空間
Student stu1 =new Student();
類型? ?變量名? ? ? ?給構造方法進行傳參
?這句話等同于 c語言中的? ?struct Student *p;
?????????????????????????? ?????????p = malloc(sizeof(struct Student));
即聲明了一個變量,也為這個變量分配了一個空間
那么如何給變量里面的內容賦值呢?
運行的結果
?
以上就是我們分裝了一個類,并且使用這個類操作,這個是我們自己封裝的類
之前我們用了系統的類Scanner sc = new Scanner(System.in);? ?
???????????????????????????????? 多了個傳遞參數,如果不傳參就跟剛才學到是一樣的
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 這個參數是傳給構造方法的
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 調用里面的方法 sc.next();? 跟我們剛才自己做的一樣
? ? ? ? ? ? ? ? 那么Student stu1 =new Student();? 這句話叫什么?? ? ?實例化一個對象
我們說的這個類是一個模板,他只有一些屬性和方法,屬性的值是多少我們是不知道的
? ? ? ? 類不能直接使用,不能直接訪問變量,需要先實例化,申請一個空間
如果我實例化對象去掉一點東西,讓它直接等于null沒有空間的
?運行結果:沒有指向內存空間的一個異常
NullPointerException基本都是由于內存訪問問題,相當于java里面的段錯誤
stu1現在是個什么東西呢???
就是直接定義了一個指針,沒有給空間直接使用
二、Java封裝之訪問修飾符
? ? ? ? 信息隱藏是oop最重要的功能之一,也是使用訪問修飾符的原因
????????
? ? ? ? ? ? ? ? 信息隱藏的原因包括:
? ? ? ? ? ? ? ? ? ? ? ? 對模塊的任何實現細節所作的更改不會影響使用該模塊的代碼
? ? ? ? ? ? ? ? ? ? ? ? 防止用戶意外修改數據
? ? ? ? ? ? ? ? ? ? ? ? 使模塊易于維護和使用(就是電腦配件)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 訪問修飾符
? ? ? ? private? ? ? ? ? ? ? ? protected? ? ? ? ? ? ? ? public? ? ? ? ? ? ? ? ? ?默認
????????????????????????????????這四個訪問修飾符有哪些區別?
? ? ????????????????? ? public? ? ? ? ?該類或非該類均可訪問
? ? ? ? ? ? ? ? ? ? ? ? private? ? ? ? 只有該類可以訪問
? ? ? ? ? ? ? ? ? ? ? ? protected? ? ? ? 該類及其子類的成員可以訪問,同一個包中的類也可訪問
? ? ? ? ? ? ? ? ? ? ? ? 默認? ? ? ? ? ? ? ? 同一個包中的類可以訪問
? ? ? ? 位置? ? ? ? ? ? ? ? ? ? ? ? private? ? ? ? ? ? ? ? 默認? ? ? ? ? ? ? ? protected? ? ? ? ? ? ? ? public
?同一個類? ? ? ? ? ? ? ? ? ? ? ? ? ? ?是? ? ? ? ? ? ? ? ? ? ? 是? ? ? ? ? ? ? ? ? ? ? ?是? ? ? ? ? ? ? ? ? ? ? ? 是?
?同一個包內的類? ? ? ? ? ? ? ? ? ?否? ? ? ? ? ? ? ? ? ? ??是? ? ? ? ? ? ? ? ? ? ? 是? ? ? ? ? ? ? ? ? ? ? ? 是
??不同包內的子類? ? ? ? ? ? ? ? 否? ? ? ? ? ? ? ? ? ? ? ? 否? ? ? ? ? ? ? ? ? ? ? ? 是? ? ? ? ? ? ? ? ? ? ? ? 是
不同包并且不是子類? ? ? ? ? ? 否? ? ? ? ? ? ? ? ? ? ? ?否? ? ? ? ? ? ? ? ? ? ? ? 否? ? ? ? ? ? ? ? ? ? ? ? ? 否
?我們編寫的代碼什么都沒寫,就代表他是默認的屬性
(第4,5,6行就是默認的屬性)
同一個類 :就是student中括號里面就是同一個類的范圍
(從第2行,到14行)
?同一個包內的類:
我們現在沒有給這個包取名字
但是可以確定這個Student? ?和Demo1 是同一個包里面的類,他們都屬于同一個文件
? ?? ? 不同包并且不是子類:?
新建一個包
包底下在創建一個類
?然后起個名字
然后Test.Java 和? ? ? ? Demo1.Java之間的關系
????????????????是不同包內并且不是子類
????????????????????????
????????????????????????? public? ? ? ? ?該類或非該類均可訪問
? ? ? ? ? ? ? ? ? ? ? ? private? ? ? ? 只有該類可以訪問
? ? ? ? ? ? ? ? ? ? ? ? protected? ? ? ? 該類及其子類的成員可以訪問,同一個包中的類也可訪問
? ? ? ? ? ? ? ? ? ? ? ? 默認? ? ? ? ? ? ? ? 同一個包中的類可以訪問
? ? ? ? 位置? ? ? ? ? ? ? ? ? ? ? ? private? ? ? ? ? ? ? ? 默認? ? ? ? ? ? ? ? protected? ? ? ? ? ? ? ? public
?同一個類? ? ? ? ? ? ? ? ? ? ? ? ? ? ?是? ? ? ? ? ? ? ? ? ? ? 是? ? ? ? ? ? ? ? ? ? ? ?是? ? ? ? ? ? ? ? ? ? ? ? 是?
?同一個包內的類? ? ? ? ? ? ? ? ? ?否? ? ? ? ? ? ? ? ? ? ??是? ? ? ? ? ? ? ? ? ? ? 是? ? ? ? ? ? ? ? ? ? ? ? 是
??不同包內的子類? ? ? ? ? ? ? ? 否? ? ? ? ? ? ? ? ? ? ? ? 否? ? ? ? ? ? ? ? ? ? ? ? 是? ? ? ? ? ? ? ? ? ? ? ? 是
不同包并且不是子類? ? ? ? ? ? 否? ? ? ? ? ? ? ? ? ? ? ?否? ? ? ? ? ? ? ? ? ? ? ? 否? ? ? ? ? ? ? ? ? ? ? ? ? 否
比如我們現在是默認的
現在這是沒問題的(第8行,和第23行)
?如果我們第八行加上private 呢?
visible是可視的意思
這個student 里面的sex變量是不可見的
這就是同一個包內的類 private 是不可以訪問的
?那么自己同一個類呢?是可以訪問的
但是我們的函數是默認權限的(第10行是默認權限)
?默認權限就有個問題
通過私有權限間接的訪問這個變量
因為這個函數是默認權限,默認權限的作用域是同一個包內
?現在我把它改成10?
?運行結果
三、Java封裝之訪問修飾符封裝屬性及方法
? ? ? ? 屬性封裝的實現:
? ? ? ? 修改屬性的可見性來限制對屬性的訪問
? ? ? ? 為每個屬性創建一對賦值方法(setter)和取值(getter)方法,用于公開對這些屬性的訪問接口
? ? ? ? ? ? ? ?在setter 和getter方法中,根據需要加入對屬性操作的限制
?我們在引用name 和age的時候,不能通過點運算符操作,可以通過共有的函數對他進行設置
剛才的代碼我們可以改動一下
,把函數執行的結果當成某個函數的傳參
運行結果
方法封裝的目的:
? ? ? ? 隱藏方法實現細節(方法體),向外部提供公開接口(方法頭),以供安全調用
? ? ? ? 簡化調用,方便修改維護
? ? ? ? 根據需要,可以私有化方法,以供內部使用 ————幫助方法helper
假如別人問你多少歲,你偷偷把年齡變成18歲
?age被我們設置成私密的,怎么辦呢?
你其實36歲,偷偷撒謊,調用了自己的函數
運行結果
你調用getage() 它偷偷的用私有的方法撒了一個謊
?
?那我們可以在stu1? 這邊? ?直接調用myage() 呢?
?顯示錯誤
是個非可視化的
?把上面的44行的stu1.age = 18;打開呢?
提示他是一個私有化的成員,都不能通過點運算符進行操作
總結一下:對屬性的封裝和對方法的封裝:就是對屬性和方法前面加上修飾符而且
四、Java封裝之構造方法
? ? ? ? UML類圖
? ? ? ? Unified Modeling Lnaguage (UML)又稱統一建模語言或者標準建模語言
? ? ? ? 類的命名盡量應用領域中的術語,
????????因明確,無歧義,以利于相互交流和理解。
? ? ? ? 類的屬性、操作中的可見性使用+、#,-分別表示public 、 protected、private
? ? ? ? 構造方法:
? ? ? ? 類的構造方法的概念和作用
? ? ? ? ? ? ? ? 構造方法負責對象的初始化工作,為對象的屬性賦合適的初始值
? ? ? ? ? ? ? ? 創建對象時,其類的構造方法確保在用戶操作對象之前,系統保證初始化的進行
? ? ? ? 構造方法的語法規則
? ? ? ? ? ? ? ? 構造方法名與類名一致
? ? ? ? ? ? ? ? 沒有返回類型
? ? ? ? ? ? ? ? 方式實現主要為字段賦初值
? ? ? ? 構造方法的調用
? ? ? ? ? ? ? ? 構造方法的調用很特別:new操作符(實例化對象的時候,自動被調用)
????????
? ? ? ? ? ? ? ? ? ? ? ? (Java系統保證每個類都有構造方法)
我們在new 的時候,就會自動調用這個方法,調用這個方法的目的,打印一句話,對里面的屬性賦初值。
????????
?運行結果
?Java語言中,方法是可重載的 函數名一樣,參數列表不同,在c中是不允許
運行結果
而且實例化的對象也是有效的
?運行結果
總結一下:構造方法的語法規則:方法名和類名一樣,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 沒有返回值
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 他的作用是為屬性賦初值
? ? ? ? ? ? ? ? 什么時候被調用呢?實例化對象的時候就被調用,而且它實例化的對象也是有效的
五、Java封裝之this 關鍵字
? ? ?
????????? 在類的方法中,使用this 關鍵字代表的是調用此方法的對象的引用
? ? ? ? this 可以看做是一個變量,他的值是當前對象的引用
? ? ? ? 使用this 可以處理方法中的成員變量和形參同名的問題
????????當在方法內需要用到調用到該方法的對象時,就可以用this
????????在類的構造方法中可以調用this ([參數列表])來調用該類的指定構造方法
第一種方法:在類的方法中,使用this 關鍵字代表的是調用此方法的對象的引用
是什么意思呢?
首先我們先copy一下,然后給他起個名字?
?可以打開這個叫this關鍵字的使用
?
?然后發現復制成功
?
我們先把對象做出來
我們看不出this 是干什么的,但是如果去調用stu1.testThis(); 的話,就會調用this.name
19行的this 肯定是個對象,這個對象引用的是誰呢?肯定是40行的stu1
運行結果
輸出了lizhaopeng
這就是第一種用法:testThis是方法,stu1是對象,是stu1這個對象調用這個方法的
調用這個方法里面有一個? this 引用的是stu1,為什么是stu1?
因為這個名字就是stu1的名字
第二種方法:this 可以看做是一個變量,他的值是當前對象的引用:
修改一下代碼
?
?運行結果
因為19行是個null,你這樣做他是沒有空間的
?可以改正一下,這里面的this 是什么呢?
this 可以看做是一個變量,他的值是當前對象的引用
就是把當前對象賦值給stutmp
?運行結果
?????????
第三種方法:? ? 使用this 可以處理方法中的成員變量和形參同名的問題
這是最常用的一種方法
我們在實例化的時候故意將
?改成
?會導致一個問題,左值和右值分不清楚,如何解決
表示對象里面的age,對象里面的name ,對象里面的score,等于你傳進來單獨的賦值
這是非常常用的方法
整體的代碼如下:
?
?運行結果
第四種方法:?當在方法內需要用到調用到該方法的對象時,就可以用this
跟第一個一樣
第五種方法:?在類的構造方法中可以調用this ([參數列表])來調用該類的指定構造方法
我現在調用的構造方法帶有三個參數吧
我能不能調用一下,只有一個參數的構造方法
?
?調用一下第7行,我們可以在三個參數的構造方法里面調用this,再加方法的列表,我什么都不調用
?
運行結果
?是不是也能調用第11行
可以是可以
但是顯示的錯誤Constructor call must be the first statement in a constructor(構造方法必須是第一條語句,在構造方法中)
因為27行,還有28行一共調用了兩個this
?
改一下
?這樣就可以啦
運行結果
六、static關鍵字的特點
? ? ? ? static 關鍵字的特點:
? ? ? ? ? ? ? ? 用來修飾類的成員——修飾成員變量的稱為類變量(靜態變量)
? ? ? ? ? ? ? ? 修飾成員的方法稱之為類方法(靜態方法)
? ? ? ? ? ? ? ? 當類被加載的時候就會被加載,優先于對象的存在
? ? ? ? ? ? ? ? 用來修飾語句塊——稱之為靜態代碼塊,先于構造方法之前執行,只會執行一次,用來對靜態成員做初始化
? ? ? ? ? ? ? ? 調用的時候可以直接通過類名.成員來進行訪問
第一個:用來修飾類的成員——修飾成員變量的稱為類變量(靜態變量):
? ? ? ??現在的代碼如下
????????
?首先static可以修飾變量,如何修飾變量呢?
那我們如何訪問 第八行的data 呢?
一般來說我們都需要實例化以后才能使用。
那能不能通過類名來訪問呢?(第27行不行)
如果你硬要通過類名不是實例化訪問的話,你這個變量就要定義成static變量(第28行)
第二個:修飾成員的方法稱之為類方法(靜態方法)
?運行結果
?那不加static可以嗎?
Cannot make a static reference to the non-static method add(int, int) from the type Demo2
?如果你不想用static怎么辦呢?
以成員函數的方式來訪問。
你必須實例化以后才能訪問,你如果不想實例化就訪問就用static(靜態成員函數)
?? 第三個:當類被加載的時候就會被加載,優先于對象的存在
第31?和32行優先于對象的存在
第27行的data通過類名,因為這個類(Student)被加載了,data也就同時加載,我們也就能訪問了
第25行的score為什么不行呢?因為它沒有static必須實例化以后才有
加上static可以不依賴于對象來訪問
成員變量是這樣的????????第27行 ????????Student.data =10;
成員函數也是這樣的????????第29行????????System.out.println("ret="+add(1,3));
第四個:? 用來修飾語句塊——稱之為靜態代碼塊,先于構造方法之前執行,只會執行一次,用來對靜態成員做初始化????????
? ? ? ? 看看下面執行的順序
?運行的結果
?在修改一下,實例化兩個對象
?運行結果
靜態代碼塊只執行了一次
構造方法執行了兩次
因為我的靜態變量(第8行)和(第2行)這個類就是 同時存在的,一開始就有,并且只有他一個
我們通過17行到20行對他靜態代碼初始化就可以啦
第五個:? 調用的時候可以直接通過類名.成員來進行訪問
????????
static關鍵字的注意事項:
? ? ? ? 靜態方法中只能訪問外部靜態成員
? ? ? ? 靜態成員不能出現this 關鍵字
? ? 第一個:? 靜態成員不能出現this 關鍵字
因為this 指的是對象的引用,靜態方法是先于對象之前的
Cannot use this in a static context?
不能使用this 在一個靜態的方法中
?第二個:? 靜態方法中只能訪問外部靜態成員
靜態方法中我們訪問name行嗎?
錯誤提示:Cannot make a static reference to the non-static field name
?他要求這面必須是一個靜態的成員
這面的靜態成員是data
方法重載:
? ? ? ? 多數程序設計語言要求為每個方法(函數)提供一個獨一無二的方法名,不存在方法重載的概念
? ? ? ? 在java中,規定方法簽名是解析方法的規則而不是方法名,為方法重載開創了條件
? ? ? ? 方法重載使得在一個類中,方法名相同而參數列表不同的方法可同時存在,代表相似的行為或功能
? ? ? ? 重載overload概念:同一個類中,同名不同參的方法稱為重載方法
? ? ? ? 注意:僅有返回值不同的方法不能稱為重載
七、java封裝之包
? ? ? ? 打包的意義
? ? ? ? ? ? ? ? 標準Java庫是由一系列包組成,包括java.lang? ? ? ? java.util? ? ? ? java.net等等
? ? ? ? ? ? ? ? 標準java包就是層次型包的結構,如硬盤上嵌套的子目錄一樣,我們可以使用嵌套層次結構來組織包
? ? ? ? ? ? ? ? ? Java的包是為了更好地規劃代碼,防止命名沖突和混亂,所以Java出現了打包機制
? ? ? ? ? ? ? ? 當把類組織起來放在一個包內之時,也就給包內的成員賦予了相互訪問的權限,您就擁有了該包內的程序代碼
? ? ? ? ? ? ? ? 包訪問權限聚集在一個包內這一做法提供了意義和理由
Package-聲明包
? ? ? ? ? ? ? ? Java程序員都可以編寫屬于自己的java包,為了保證包名唯一性,要求程序員在自己定義包的名字前加上唯一前綴
? ? ? ? ? ? ? ? 由于互聯網上的域名稱不會重復,所以推薦采用公司在互聯網上的域名的倒置作為包的唯一前綴
? ? ? ? ?一個類可以使用同一個包中的所有類
? ? ? ? 一個類可以使用其他包中的所有公開類
? ? ? ? 怎么使用其他包中的公開類
? ? ? ? ? ? ? ? 在每個類簽名加上完整包名,例如:
? ? ? ? ? ? ? ? ? ? ? ? java.util.Data today = new java.util.Date();
? ? ? ? ? ? ? ? 更簡潔更通用的方式:使用import語句來導包(eclipse? ? ctrl+shift+o)
? ? ? ? ? ? ? ? ? ? ? ? import? ?java.util.Date;
? ? ? ? ? ? ? ? ? ? ? ? ..............
? ? ? ? ? ? ? ? ? ? ? ? Date? today = new Date();
? ? ? ? ? ? ? ? 可以import特定類,也可以導入整個包。通過在源代碼文件的頂部(在打包語句后)使用import語句來實現import? ?java.util.*;
? ? ? ? ? ? ??
比如我們做一個scanner
它顯示有錯誤
Multiple markers at this line
?? ?- Scanner cannot be resolved to?a type
?
第一種方法:
然后我們點擊一下ctrl +shift +o 就可以啦
這樣40行的錯誤就沒有了
發現第一行多出來這么一行話
?
?第二種方法:
或者我們把這個第一行import ....去掉,
然后給他加上一個完整的路徑
但是這種方法比較被動
?
那我們現在實際來建立一個包
?
?
?
?這兩個Demonew名字一樣,所處的包不一樣
?比如我們.learn包下面的Demo3.java下面有一個main函數
它可不可以用.learn包下面的Demonew的.java 呢?
?那我們同一個包底下,(.learn包)
是不是可以用他的類呢?(Demo3.java 和Demonew)
?運行一下看一下結果
?同樣的,我們用另一個Demonew 呢?
就是.use下面的那個
?記得加上訪問的權限
?記得加上訪問的權限
給.use 下面的Demonew
?這塊可以用路徑來訪問
?
?運行結果
?在.learn 下面有Demo3.java? 和Demonew.java
在use下有Demonew.java
先修改一下代碼,先刪掉.learn 下面的Demonew.java
?然后在.learn的Demo3下面,已經變成這樣了
如何解決?ctrl +shirt? + o
?
把demonew導進來?
?
運行一下.learn 里面的demonew
顯示namenull
?為什么是null,因為我們沒有給這個name 賦初值
?現在我們準備在.learn下面再建一個Demonew
?然后
?現在有兩個demonew ,對于demo3來說,我們用誰呢?
先運行看一下
他現在還是用.use 包下面的
?那么如果我把import com.chenlichen.use.Demonew;這個東西去掉呢?
那么它現在就是用的.learn 下面的
總結
以上是生活随笔為你收集整理的Java:封装的概念,UML类图,构造方法,this关键字,static关键字,方法重载,包package的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java:Java的输入类Scanner
- 下一篇: java美元兑换,(Java实现) 美元