小編給大家分享一下Java三大特性之封裝的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
在義馬等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供做網(wǎng)站、網(wǎng)站制作 網(wǎng)站設(shè)計制作按需定制設(shè)計,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計,成都全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站建設(shè),義馬網(wǎng)站建設(shè)費用合理。
面向?qū)ο蟮木幊陶Z言,擁有三大特性,分別是:“封裝”,“繼承”,“多態(tài)”。
封裝
在面向?qū)ο缶幊讨?,封裝封裝(encapsulation)從字面上來理解就是包裝的意思,是 指利用抽象數(shù)據(jù)類型將數(shù)據(jù)和基于數(shù)據(jù)的操作封裝在一起 ,使其構(gòu)成一個不可分割的獨立實體。其實就是將對象運行所需的方法和數(shù)據(jù)封裝在程序公布其接口,數(shù)據(jù)被保護(hù)在抽象數(shù)據(jù)類型的內(nèi)部,盡可能地隱藏內(nèi)部的細(xì)節(jié),只保留一些對外接口使之與外部發(fā)生聯(lián)系。也就是說用戶是無需知道對象內(nèi)部的細(xì)節(jié)(當(dāng)然也無從知道),但可以通過該對象對外的提供的接口來訪問該對象,通俗點就是是其他附加到這些接口上的對象不需要關(guān)心對象實現(xiàn)的方法即可使用這個對象。這個概念就是“ 不要告訴我你是怎么做的,只要做就可以了 “。
所以封裝把一個對象的屬性私有化,同時提供一些可以被外界訪問的屬性的方法,如果不想被外界方法,我們大可不必提供方法給外界訪問。但是如果一個類沒有提供給外界訪問的方法,那么這個類也沒有什么意義了。
比如我們將一個對象看做是一個房子,里面的漂亮的壁紙,如沙發(fā)、電視、空調(diào)等都是該房子的私有屬性,但是如果沒有墻遮擋,那不就沒有一點兒隱私了嗎!就是因為有了遮擋的墻,我們既能夠有自己的隱私 而且我們可以隨意的更改里面的擺設(shè)而不會影響到其他的。但是如果沒有門窗,一個包裹的嚴(yán)嚴(yán)實實的黑盒子,又有什么存在的意義呢?所以通過門窗別人也能夠看到里面的風(fēng)景。所以說門窗就是房子對象留給外界訪問的接口。
一般在類里要將屬性前添加 private 修飾符。然后定義getter和setter方法。然后在我們的 main 函數(shù)里的對象,不能再直接調(diào)用屬性了,只能通過getter和setter方法進(jìn)行調(diào)用。
封裝的三大好處
1、良好的封裝能夠減少耦合。
2、類內(nèi)部的結(jié)構(gòu)可以自由修改。
3、可以對成員進(jìn)行更精確的控制。
4、隱藏信息,實現(xiàn)細(xì)節(jié)。
修飾符
大家首先要先了解一下什么是修飾符,訪問修飾符可以用來修飾屬性和方法的訪問范圍。
在面向?qū)ο蟮倪^程中,我們通過 權(quán)限控制 對封裝好的類加上權(quán)限,來限制外來者對類的操縱,借以達(dá)到保障類中數(shù)據(jù)和方法的安全的目的。可以這么說:一個類就是一個封裝了相關(guān)屬性及方法的邏輯實體。對于對象中的某些屬性或者方法來說,它們可以是私有的,不能被外界訪問。也可以是共有的,能夠被外界任何人員訪問。通過這種方式,對象對內(nèi)部數(shù)據(jù)提供了不同級別的保護(hù),以防止程序中無關(guān)的部分意外的改變或錯誤的使用了對象的私有部分,從而使得程序出現(xiàn)不要的錯誤。
java中4中修飾符分別為public、protectd、default、private。這就說明了面向?qū)ο蟮姆庋b性,所有我們要盡量讓權(quán)限降到最低,從而安全性提高。
如圖,代表了不同的訪問修飾符的訪問范圍,比如private修飾的屬性或者方法,只能在本類中訪問或者使用。什么修飾符都不加的話默認(rèn)是default,默認(rèn)在當(dāng)前類中和同一包下都可以訪問和使用。
訪問權(quán)限 類 包 子類 其他包
public ∨ ∨ ∨ ∨
protect ∨ ∨ ∨ ×
default ∨ ∨ × ×
private ∨ × × ×
如果沒有在屬性前面添加任何修飾符,默認(rèn)是default權(quán)限,我們通過創(chuàng)建對象就可以直接對屬性值進(jìn)行修改,沒有體現(xiàn)封裝的特性。這在程序設(shè)計中都是不安全的,所以我們需要利用封裝,來改進(jìn)我們的代碼。
修飾符舉例
首先我們先定義四個類Person,Parent,Teacher,Student,分別比較其他包,子類,包,本類的區(qū)別。每個類的位置圖所示。
package com.java.test; public class Person { public String name = "張三"; public void introduceMyself(){ System.out.println(name); } }
name是public的,若編譯沒有報錯說明public變量擁有本類的訪問權(quán)限。
package com.java.test; public class Student { Person p = new Person(); public void test(){ System.out.println(p.uname); } }
Student和 Person在同一個包內(nèi),若編譯沒有報錯,說明變量在相同擁有包內(nèi)的訪問權(quán)限。
package com.java.test1; import com.java.test.Person; public class Teacher extends Person { public int age; Person p = new Person(); public void test1(){ System.out.println(p.uname); } }
Student和 Person不在同一個包內(nèi),但是Teacher繼承了Person類,若編譯沒有報錯,說明變量擁有子包內(nèi)的訪問權(quán)限
package com.java.test1; import com.java.test.Person; public class Parents { public String uname = "haha"; Person p = new Person(); public void test2(){ System.out.println(p.uname); } }
Parent和Person不在同一個包內(nèi),若編譯沒有報錯,則說明變量擁有白外的訪問權(quán)限
上面測試了之后,如果均能編譯通過,就說明用public修飾的類在本類、同包、子類、其他包中互相訪問都是可以的
同樣開始測試protected權(quán)限問題,如果Person,Teacher,Student能編譯通過,就說明用protected修飾的類在本類、同包、子類中互相訪問都是可以的,而Parent編譯不通過說明protected不可以在包外沒有繼承關(guān)系的類中互相訪問。
同樣開始測試default權(quán)限問題,如果Person,Student能編譯通過,就說明用default修飾的類在本類、同包、子類中互相訪問都是可以的,而Parent,Teacher編譯不通過說明default修飾的類可以在包外不管有沒有繼承關(guān)系的類都不可以互相訪問
同樣開始測試private權(quán)限問題,如果Person能編譯通過,就說明用private修飾的類在本類、同包、子類中互相訪問都是可以的,而Parent,Teacher,Student編譯不通過說明private修飾的類只能在本類中訪問。
一般在類里要將屬性前添加private修飾符。然后定義getter和setter方法。然后在我們的 main 函數(shù)里的對象,不能再直接調(diào)用屬性了,只能通過getter和setter方法進(jìn)行調(diào)用。
包
我先給大家講一下包的作用
有時候會遇到程序的類名可能是重復(fù)的,我們就可以用包的概念來解決我們的問題。包的作用就是管理Java文件,解決同名文件沖突。這就和衣柜相類似。衣柜是不是有不同的隔斷和抽屜,我們將衣服分門別類地放好,更有利與有利于我們管理。
定義一個包,我們使用package關(guān)鍵字,加上我們的包名。
package com.java.test; //注意:必須放在源程序的第一行,包名可用”.”號隔開 ,包的命名規(guī)范是全小寫字母拼寫
Java系統(tǒng)中常用的包
java.(功能).(類) java.lang.(類) 包含java語言基礎(chǔ)的類 java.util.(類) 包含語言中各種工具類 java.io.(類) 包含輸入、輸出相關(guān)的類
在不同包中使用另一個文件中的類,就需要用到import關(guān)鍵字。比如import com.java.test1.test.java,同時如果import com.java.test1*這是將包下的所有文件都導(dǎo)入進(jìn)來。
this 關(guān)鍵字
一、this關(guān)鍵字主要有三個應(yīng)用:
(1)this調(diào)用本類中的屬性,也就是類中的成員變量;
(2)this調(diào)用本類中的其他方法;
(3)this調(diào)用本類中的其他構(gòu)造方法,調(diào)用時要放在構(gòu)造方法的首行。
Public Class Student { public Student(String name) { //定義一個帶形式參數(shù)的構(gòu)造方法 } public Student() { //定義一個方法,名字與類相同故為構(gòu)造方法 this(“Hello!”); } String name; //定義一個成員變量name private void SetName(String name) { //定義一個參數(shù)(局部變量)name this.name=name; //將局部變量的值傳遞給成員變量 } }
如上面這段代碼中,有一個成員變量name,同時在方法中有一個形式參數(shù),名字也是name,然后在方法中將形式參數(shù)name的值傳遞給成員變量name。
this這個關(guān)鍵字其代表的就是對象中的成員變量或者方法。也就是說,如果在某個變量前面加上一個this關(guān)鍵字,其指的就是這個對象的成員變量或者方法,而不是指成員方法的形式參數(shù)或者局部變量。為此在上面這個代碼中,this.name代表的就是對象中的成員變量,又叫做對象的屬性,而后面的name則是方法的形式參數(shù),代碼this.name=name就是將形式參數(shù)的值傳遞給成員變量。
如果一個類中有多個構(gòu)造方法,因為其名字都相同,跟類名一致,那么這個this到底是調(diào)用哪個構(gòu)造方法呢?其實,這跟采用其他方法引用構(gòu)造方法一樣,都是通過形式參數(shù)來調(diào)用構(gòu)造方法的。如上例中,this關(guān)鍵字后面加上了一個參數(shù),那么就表示其引用的是帶參數(shù)的構(gòu)造方法。如果現(xiàn)在有三個構(gòu)造方法,分別為不帶參數(shù)、帶一個參數(shù)、帶兩個參數(shù)。那么Java編譯器會根據(jù)所傳遞的參數(shù)數(shù)量的不同,來判斷該調(diào)用哪個構(gòu)造方法。從上面示例中可以看出,this關(guān)鍵字不僅可以用來引用成員變量,而且還可以用來引用構(gòu)造方法。
內(nèi)部類
內(nèi)部類( Inner Class )我們從外面看是非常容易理解的,內(nèi)部類就是將一個類的定義放在另一個類的定義內(nèi)部。當(dāng)然與之對應(yīng),包含內(nèi)部類的類被稱為外部類。
很多初學(xué)者一定會問那為什么要將一個類定義在另一個類里面呢?
我們程序設(shè)計中有時候會存在一些使用接口很難解決的問題,這時我們就可以利用內(nèi)部類提供的、可以繼承多個具體的或者抽象的類的能力來解決這些程序設(shè)計問題??梢赃@樣說,接口只是解決了部分問題,而內(nèi)部類使得多重繼承的解決方案變得更加完整。
在《Think in java》中有這樣一句話:使用內(nèi)部類最吸引人的原因是:每個內(nèi)部類都能獨立地繼承一個(接口的)實現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(接口的)實現(xiàn),對于內(nèi)部類都沒有影響。
public interface Father { } public interface Mother { } public class Son implements Father, Mother { } public class Daughter implements Father{ class Mother_ implements Mother{ } }
內(nèi)部類特性
1、 內(nèi)部類可以用多個實例,每個實例都有自己狀態(tài)信息,并且與其他外圍對象信息相互獨立。
2、 在單個外圍類中,可以讓多個內(nèi)部類以不同的方式實現(xiàn)同一個接口,或者繼承同一個類。
3、 創(chuàng)建內(nèi)部類對象的時刻并不依賴于外圍類對象的創(chuàng)建。
4、 內(nèi)部類并沒有令人迷惑的“is-a”關(guān)系,他就是一個獨立的實體。
5、 內(nèi)部類提供了更好的封裝,除了該外圍類,其他類都不能訪問。
package com.java.test; public class OuterClass { private String name ; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void display(){ System.out.println("調(diào)用的是OuterClass的display"); } public class InnerClass{ public InnerClass(){ name = "chenssy"; age = 23; } public OuterClass getOuterClass(){ return OuterClass.this; } public void display(){ System.out.println("name:" + getName() +" ;age:" + getAge()); } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); innerClass.display(); innerClass.getOuterClass().display(); } } name:chenssy ;age:23
調(diào)用的是OuterClass的display
我們需要明確一點,內(nèi)部類是個編譯時的概念,一旦編譯成功后,它就與外圍類屬于兩個完全不同的類(當(dāng)然他們之間還是有聯(lián)系的)。
我們還看到了如何來引用內(nèi)部類:引用內(nèi)部類我們需要指明這個對象的類型: OuterClasName.InnerClassName 。同時如果我們需要創(chuàng)建某個內(nèi)部類對象,必須要利用外部類的對象通過.new來創(chuàng)建內(nèi)部類: OuterClass.InnerClass innerClass = outerClass.new InnerClass();。
同時如果我們需要生成對外部類對象的引用,可以使用OuterClassName.this,這樣就能夠產(chǎn)生一個正確引用外部類的引用了。
在Java中內(nèi)部類主要分為成員內(nèi)部類、局部內(nèi)部類、匿名內(nèi)部類、靜態(tài)內(nèi)部類。
成員內(nèi)部類
成員內(nèi)部類也是最普通的內(nèi)部類,它是外圍類的一個成員,所以他是可以無限制的訪問外圍類的所有 成員屬性和方法,盡管是private的,但是外圍類要訪問內(nèi)部類的成員屬性和方法則需要通過內(nèi)部類實例來訪問。
在成員內(nèi)部類中要注意兩點,
成員內(nèi)部類中不能存在任何static的變量和方法;
成員內(nèi)部類是依附于外圍類的,所以只有先創(chuàng)建了外圍類才能夠創(chuàng)建內(nèi)部類。
public class OuterClass { private String str; public void outerDisplay(){ System.out.println("outerClass..."); } public class InnerClass{ public void innerDisplay(){ //使用外圍內(nèi)的屬性 str = "chenssy..."; System.out.println(str); //使用外圍內(nèi)的方法 outerDisplay(); } } /*推薦使用getxxx()來獲取成員內(nèi)部類,尤其是該內(nèi)部類的構(gòu)造函數(shù)無參數(shù)時 */ public InnerClass getInnerClass(){ return new InnerClass(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); OuterClass.InnerClass inner = outer.getInnerClass(); inner.innerDisplay(); } }
個人推薦使用getxxx()來獲取成員內(nèi)部類,尤其是該內(nèi)部類的構(gòu)造函數(shù)無參數(shù)時 。
句局部內(nèi)部類
局部內(nèi)部類,是嵌套在方法和作用域內(nèi)的,對于這個類的使用主要是應(yīng)用與解決比較復(fù)雜的問題,想創(chuàng)建一個類輔助我們的解決方案,到那時不希望這個類是公共的,所以我們就可以創(chuàng)建局部內(nèi)部類。
局部內(nèi)部類和成員內(nèi)部類一樣被編譯,他只能在該方法和屬性中使用,不在該方法和屬性就會失效。
定義在方法里:
public class Parcel5 { public Destionation destionation(String str){ class PDestionation implements Destionation{ private String label; private PDestionation(String whereTo){ label = whereTo; } public String readLabel(){ return label; } } return new PDestionation(str); } public static void main(String[] args) { Parcel5 parcel5 = new Parcel5(); Destionation d = parcel5.destionation("chenssy"); } }
定義在作用域內(nèi):
public class Parcel6 { private void internalTracking(boolean b){ if(b){ class TrackingSlip{ private String id; TrackingSlip(String s) { id = s; } String getSlip(){ return id; } } TrackingSlip ts = new TrackingSlip("chenssy"); String string = ts.getSlip(); } } public void track(){ internalTracking(true); } public static void main(String[] args) { Parcel6 parcel6 = new Parcel6(); parcel6.track(); } }
匿名內(nèi)部類
public class OuterClass { public InnerClass getInnerClass(final int num,String str2){ return new InnerClass(){ int number = num + 3; public int getNumber(){ return number; } }; /* 注意:分號不能省 */ } public static void main(String[] args) { OuterClass out = new OuterClass(); InnerClass inner = out.getInnerClass(2, "chenssy"); System.out.println(inner.getNumber()); } } interface InnerClass { int getNumber(); }
1、 匿名內(nèi)部類是沒有訪問修飾符的。
2、 new 匿名內(nèi)部類,這個類首先是要存在的。如果我們將那個InnerClass接口注釋掉,就會出現(xiàn)編譯出錯。
3、 注意getInnerClass()方法的形參,第一個形參是用final修飾的,而第二個卻沒有。同時我們也發(fā)現(xiàn)第二個形參在匿名內(nèi)部類中沒有使用過,所以當(dāng)所在方法的形參需要被匿名內(nèi)部類使用,那么這個形參就必須為final。
4、 匿名內(nèi)部類是沒有構(gòu)造方法的。因為它連名字都沒有何來構(gòu)造方法。
靜態(tài)內(nèi)部類
static可以修飾成員變量,方法,代碼塊,其他還可以修飾內(nèi)部類,使用static修飾的內(nèi)部類我們稱之為靜態(tài)內(nèi)部類,不過我們更喜歡稱之為嵌套內(nèi)部類。靜態(tài)內(nèi)部類與非靜態(tài)內(nèi)部類之間最大的區(qū)別就是非靜態(tài)內(nèi)部類在編譯完成之后會隱含的保存著一個引用,該以及用是指向他的外圍內(nèi)。但是靜態(tài)內(nèi)部類卻沒有,這就意味著靜態(tài)內(nèi)部類創(chuàng)建不需要依賴外圍類,并且他不能使用任何外圍類的非static成員變量和方法。
public class OuterClass { private String sex; public static String name = "chenssy"; /** *靜態(tài)內(nèi)部類 */ static class InnerClass1{ /* 在靜態(tài)內(nèi)部類中可以存在靜態(tài)成員 */ public static String _name1 = "chenssy_static"; public void display(){ /* * 靜態(tài)內(nèi)部類只能訪問外圍類的靜態(tài)成員變量和方法 * 不能訪問外圍類的非靜態(tài)成員變量和方法 */ System.out.println("OutClass name :" + name); } } /** * 非靜態(tài)內(nèi)部類 */ class InnerClass2{ /* 非靜態(tài)內(nèi)部類中不能存在靜態(tài)成員 */ public String _name2 = "chenssy_inner"; /* 非靜態(tài)內(nèi)部類中可以調(diào)用外圍類的任何成員,不管是靜態(tài)的還是非靜態(tài)的 */ public void display(){ System.out.println("OuterClass name:" + name); } } /** * @desc 外圍類方法 * @author chenssy * @data 2013-10-25 * @return void */ public void display(){ /* 外圍類訪問靜態(tài)內(nèi)部類:內(nèi)部類. */ System.out.println(InnerClass1._name1); /* 靜態(tài)內(nèi)部類 可以直接創(chuàng)建實例不需要依賴于外圍類 */ new InnerClass1().display(); /* 非靜態(tài)內(nèi)部的創(chuàng)建需要依賴于外圍類 */ OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2(); /* 方位非靜態(tài)內(nèi)部類的成員需要使用非靜態(tài)內(nèi)部類的實例 */ System.out.println(inner2._name2); inner2.display(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.display(); } }
以上是“Java三大特性之封裝的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!